Reset row_factory attribute of an Python sqlite3 object - python

How can I reset the "row_factory" attribute of an sqlite3 connection object after setting it to "sqlite3.Row"? For instance:
import sqlite3
con = sqlite3.connect("db.dat", isolation_level=None)
con.row_factory = sqlite3.Row
cur = con.execute("insert into test1 (name, last) values (?, ?)", ("John","doe"))
cur = con.execute("insert into test1 (name, last) values (?, ?)", ("Liz","doe"))
cur.execute("select * from test1")
cur.fetchone() # gets {'name':'john', 'last':'doe'}
# Now I want to get a tuple when calling fetchone
con.row_factory = None
cur.fetchone() #Throw error
delattrib(con, "row_factory") # causes segmentation fault on Windows
I can't find an answer anywhere and the only solution (other than casting the dictionary) is to reopen the db connection. I read the documentation for the sqlite3 module, but it doesn't mention anything to reset the attribute back to its default state.
Thank you

Related

View Function used to work now it does not

import sqlite3
def create_table():
connection = sqlite3.connect('lite.db')
cursor = connection.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS shop (item TEXT, quantity INTEGER, price REAL)') #you write the SQL code in between brackets
connection.commit()
connection.close()
create_table()
def insert(item,quantity,price):
connection = sqlite3.connect('lite.db')
cursor = connection.cursor()
cursor.execute("INSERT INTO shop VALUES (?,?,?)", (item,quantity,price)) # inserting data
connection.commit()
connection.close()
insert('Wine Glass', 10, 5)
insert('Coffe Cup', 5, 2)
insert('Plate', 20, 10)
def view():
connection = sqlite3.connect('lite.db')
cursor = connection.cursor()
cursor.execute('SELECT ALL FROM shop ')
rows = cursor.fetchall()
connection.close()
return rows
def delete_item(item):
connection = sqlite3.connect('lite.db')
cursor = connection.cursor()
cursor.execute("DELETE * FROM shop WHERE item = ?", (item,)) # inserting data
connection.commit()
connection.close()
print(view())
delete_item('Wine Glass')
print(view())
Error Message:
cursor.execute('SELECT ALL FROM shop ')
sqlite3.OperationalError: near "FROM": syntax error
It used to work and then I added the delete function and now it gives me this syntax error, I didn't even make any changes on that function. The code is based on a Udemy tutorial, and with the same changes applied on the video I got this error message but the tutor did not. As you can guess I am pretty new to this stuff and I cant decipher the error message, or at least if it means any more than the obvious. So yeah thanks in advance
SELECT ALL should be SELECT ALL * or just SELECT * to select all columns in all rows. See the syntax here.
DELETE * FROM shop should be DELETE FROM shop. DELETE deletes whole rows, it doesn't need a list of columns. See the syntax here.

sqlite3.OperationalError: no such table: store

I'm learning sqlite3 with python, but I've been facing this error: "sqlite3.OperationalError: no such table: store". How do I get around this?
import sqlite3
def create_table(): #function to create the table
conn = sqlite3.connect('lite.db')
cur = conn.cursor() # creating th cursor object
cur.execute("CREATE TABLE IF NOT EXISTS store (item TEXT, quantity INTEGER, price REAL)")
conn.commit()
conn.close()
def insert(item, quantity, price ): #function to insert into the table
conn = sqlite3.connect('lite.db')
cur = conn.cursor() # creating th cursor object
cur.execute("INSERT INTO store VALUES(?,?,?)", (item, quantity, price))
conn.commit()
conn.close()
insert("biscuits",500,20000)
def view():
conn = sqlite3.connect('lite.db')
cur = conn.cursor()
cur.execute("SELECT * FROM store")
rows = cur.fetchall()
return rows
conn.close()
print(view())
You forgot to call the create_table method before calling insert. As you haven't called the the create_table method the insert method tries to insert a record to a non existing table.
The solution is simply to call the create_table method before insert as follows:
create_table() # Add this line before the insert
insert("biscuits", 500, 20000)

How do I make a return statement from this loop

I have this code and i need to get the lastrowid as a return statement. How can i fix it
def main():
while True:
#code here
for item in name2:#break
conn = sqlite3.connect("foods.db")
cursor = conn.cursor()
cursor.execute("INSERT INTO INPUT33 (NAME) VALUES (?);", (name2,))
cursor.execute("select MAX(rowid) from [input33];")
conn.commit()
conn.close()
for rowid in cursor:break
for elem in rowid:
return rowid#this is not working
print(m)
You closed the database, so any cursor no longer has access to the data. Retrieve the data before closing. I am assuming here that you have a reason to re-open the database in a loop here.
def main():
while True:
for item in name2:
conn = sqlite3.connect("foods.db")
cursor = conn.cursor()
with conn:
cursor.execute("INSERT INTO INPUT33 (NAME) VALUES (?);", (name2,))
cursor.execute("select MAX(rowid) from [input33];")
rowid = cursor.fetchone()[0]
conn.close()
return rowid

MySQL did not give an error, but none of the rows got filled

I tried to fill a table in a database using MySQLdb. It did not give any errors, and once gave the warning
main.py:23: Warning: Data truncated for column 'other_id' at row 1
cur.execute("INSERT INTO map VALUES(%s,%s)",(str(info[0]).replace('\n',''), str(info[2].replace('\n','').replace("'",""))))
so I thought it was working fine. However, when it was finished and I did a row count it turned out that nothing was added. Why was the data not added to the database? The code is below
def fillDatabase():
db = MySQLdb.connect(host="127.0.0.1",
user="root",
passwd="",
db="uniprot_map")
cur = db.cursor()
conversion_file = open('idmapping.dat')
for line in conversion_file:
info = line.split('\t')
cur.execute("INSERT INTO map VALUES(%s,%s)",(str(info[0]).replace('\n',''), str(info[2].replace('\n','').replace("'",""))))
def test():
db = MySQLdb.connect(host="127.0.0.1",
user="root",
passwd="",
db="uniprot_map")
cur = db.cursor()
cur.execute("SELECT COUNT(*) FROM map")
rows = cur.fetchall()
for row in rows:
print row
def main():
fillDatabase()
test()
You need to do a db.commit() after adding all of the entries. Even if the update is not transactional, the DBAPI imposes an implicit transaction on every change.

Checking if a postgresql table exists under python (and probably Psycopg2)

How can I determine if a table exists using the Psycopg2 Python library? I want a true or false boolean.
How about:
>>> import psycopg2
>>> conn = psycopg2.connect("dbname='mydb' user='username' host='localhost' password='foobar'")
>>> cur = conn.cursor()
>>> cur.execute("select * from information_schema.tables where table_name=%s", ('mytable',))
>>> bool(cur.rowcount)
True
An alternative using EXISTS is better in that it doesn't require that all rows be retrieved, but merely that at least one such row exists:
>>> cur.execute("select exists(select * from information_schema.tables where table_name=%s)", ('mytable',))
>>> cur.fetchone()[0]
True
I don't know the psycopg2 lib specifically, but the following query can be used to check for existence of a table:
SELECT EXISTS(SELECT 1 FROM information_schema.tables
WHERE table_catalog='DB_NAME' AND
table_schema='public' AND
table_name='TABLE_NAME');
The advantage of using information_schema over selecting directly from the pg_* tables is some degree of portability of the query.
select exists(select relname from pg_class
where relname = 'mytablename' and relkind='r');
The first answer did not work for me. I found success checking for the relation in pg_class:
def table_exists(con, table_str):
exists = False
try:
cur = con.cursor()
cur.execute("select exists(select relname from pg_class where relname='" + table_str + "')")
exists = cur.fetchone()[0]
print exists
cur.close()
except psycopg2.Error as e:
print e
return exists
#!/usr/bin/python
# -*- coding: utf-8 -*-
import psycopg2
import sys
con = None
try:
con = psycopg2.connect(database='testdb', user='janbodnar')
cur = con.cursor()
cur.execute('SELECT 1 from mytable')
ver = cur.fetchone()
print ver //здесь наш код при успехе
except psycopg2.DatabaseError, e:
print 'Error %s' % e
sys.exit(1)
finally:
if con:
con.close()
I know you asked for psycopg2 answers, but I thought I'd add a utility function based on pandas (which uses psycopg2 under the hood), just because pd.read_sql_query() makes things so convenient, e.g. avoiding creating/closing cursors.
import pandas as pd
def db_table_exists(conn, tablename):
# thanks to Peter Hansen's answer for this sql
sql = f"select * from information_schema.tables where table_name='{tablename}'"
# return results of sql query from conn as a pandas dataframe
results_df = pd.read_sql_query(sql, conn)
# True if we got any results back, False if we didn't
return bool(len(results_df))
I still use psycopg2 to create the db-connection object conn similarly to the other answers here.
The following solution is handling the schema too:
import psycopg2
with psycopg2.connect("dbname='dbname' user='user' host='host' port='port' password='password'") as conn:
cur = conn.cursor()
query = "select to_regclass(%s)"
cur.execute(query, ['{}.{}'.format('schema', 'table')])
exists = bool(cur.fetchone()[0])
Expanding on the above use of EXISTS, I needed something to test table existence generally. I found that testing for results using fetch on a select statement yielded the result "None" on an empty existing table -- not ideal.
Here's what I came up with:
import psycopg2
def exist_test(tabletotest):
schema=tabletotest.split('.')[0]
table=tabletotest.split('.')[1]
existtest="SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '"+schema+"' AND table_name = '"+table+"' );"
print('existtest',existtest)
cur.execute(existtest) # assumes youve already got your connection and cursor established
# print('exists',cur.fetchall()[0])
return ur.fetchall()[0] # returns true/false depending on whether table exists
exist_test('someschema.sometable')
You can look into pg_class catalog:
The catalog pg_class catalogs tables and most everything else that has
columns or is otherwise similar to a table. This includes indexes (but
see also pg_index), sequences (but see also pg_sequence), views,
materialized views, composite types, and TOAST tables; see relkind.
Below, when we mean all of these kinds of objects we speak of
“relations”. Not all columns are meaningful for all relation types.
Assuming an open connection with cur as cursor,
# python 3.6+
table = 'mytable'
cur.execute(f"SELECT EXISTS(SELECT relname FROM pg_class WHERE relname = {table});")
if cur.fetchone()[0]:
# if table exists, do something here
return True
cur.fetchone() will resolve to either True or False because of the EXISTS() function.

Categories

Resources