I've been following this 5 part tutorial from this YouTube playlist: https://www.youtube.com/playlist?list=PLQVvvaa0QuDezJh0sC5CqXLKZTSKU1YNo
I'm using Jupyter notebook with Python with the following code:
import sqlite3
import time
import datetime
import random
conn = sqlite3.connect("tutorial2.db")
c = conn.cursor()
Then I create several functions.
def create_table():
c.execute('CREATE TABLE IF NOT EXISTS stuffToPlot (unix REAL, datestamp TEXT,
keyword TEXT, value REAL)')
def data_entry():
c.execute("INSERT INTO stuffToPlot VALUES (145123542, '2016-01-03',
'Python', 7)")
conn.commit()
c.close()
conn.close()
create_table()
data_entry()
It works fine the first time, and generates a db file in C:\Users\Michael
However, when I try to run only the create_table() function again, I get the following error:
ProgrammingError: Cannot operate on a closed cursor.
Anyone able to help resolving this issue would be greatly appreciated!
The error is pretty explicit: You cannot run queries on closed cursors. Here it's even worse since you have also closed the connection at the first call of the data_entry() function.
I would advise on opening a cursor for each query, and then closing it after completing the query, and only closing the connection at the end of your script:
import sqlite3
import time
import datetime
import random
conn = sqlite3.connect("tutorial2.db")
def create_table():
c = conn.cursor()
c.execute('CREATE TABLE IF NOT EXISTS stuffToPlot (unix REAL, datestamp TEXT, keyword TEXT, value REAL)')
c.close()
def data_entry():
c = conn.cursor()
c.execute("INSERT INTO stuffToPlot VALUES (145123542, '2016-01-03', 'Python', 7)")
conn.commit()
c.close()
create_table()
data_entry()
By moving the conn.close() statement after you have completed all of your queries, and opening the cursors only when you need them, the error won't occur anymore.
EDIT : What is happening in your video is the following:
He first executes the whole script once.
He comments the line that creates the table.
He executes the whole script a second time.
I think you are probably entering the commands in a python interactive session, which is not equivalent to what he is doing in the video, because when he re-executes the script, a new connection and cursor are created, whereas if you're only trying to call the function again, the cursor and connection are already closed, which causes the error.
Related
I have a stored procedure in Postgres called sales, and it works well from pgadmin:
CALL sales();
However, when I call it from Python:
import psycopg2
conn = psycopg2.connect (host ....)
cur = conn.cursor()
cur.callproc('sales')
conn.commit()
I get the following error message:
psycopg2.ProgrammingError: sales() is a procedure
LINE 1: SELECT * FROM sales()
^
HINT: To call a procedure, use CALL.
Assuming your procedure is called sales, you just need to "call" it e.g. CALL sales()
https://www.postgresql.org/docs/11/sql-call.html
I see what you are getting at, the python documentation here is misleading
"Calling a PostgreSQL stored procedure in Python steps"
http://www.postgresqltutorial.com/postgresql-python/call-stored-procedures/
Essentially the callproc is currently outdated (written for postgres 10 and below) and still considers procedures to be a function. So unless they update this, you will need to execute your own SQL in this instance like so
cur.execute("CALL sales();")
or if the sales procedure required inputs:
cur.execute("CALL sales(%s, %s);", (val1, val2))
Try this code to call PostgreSQL Stored_Procedure in Python Script :
import pyodbc
import psycopg2
import io
from sqlalchemy import create_engine
from urllib.parse import quote
#define your PostgreSQL connection here:
host="Provide Host Name"
dbname="Provide Database Name"
user="Provide User"
password="Provide Password"
engine=create_engine('postgresql://{}:{}#{}:5432/{}.format(user,quote(password),host,dbname))
conn=engine.raw_connection()
cur=conn.cursor()
#This will be your code to call stored procedure:
cur.execute('''call storedProcedureName()''')
conn.commit() # This is mandatory because we want to commit changes to DB
cur.close()
conn.close()
time.sleep(60) # timeout (optional)
I tried inserting the values into the DB through python. However i do not get any error but i do not see it updating in DB. Please advice.
#!/usr/bin/python
import MySQLdb
val = MySQLdb.connect(host='localhost', user='root', passwd='root123',
db='expenses')
def access_db(val):
access = val.cursor()
sql = """Insert into monthly values (2,'Food',1000)"""
access.execute(sql)
val.commit()
val.close()
Output from DB after the script execution:
MariaDB[expenses]> select * from monthly;
SL_no Type Amount
1 Fuel 500
I do not find the second entry in Db.
I dont think you are calling the access_db() function anywhere
Here's my code
import sqlite3
conn = sqlite3.connect('arbitrary.db')
c = conn.cursor()
data = ['sampletext',42]
c.execute("CREATE TABLE IF NOT EXISTS t1(link TEXT,story_id INTEGER)")
c.execute("INSERT INTO t1 (link, story_id) VALUES (?,?)", data)
conn.commit()
conn.close()
It runs without error and doesn't throw any parsing errors, but once the script closes and I go to open the db file, It's still empty. am I making a mistake somewhere?
Appreciate the help in advance :)
The book named "Practical Programming: 2nd Edition" has conflicting code. This is the start of my code:
import sqlite3
con = sqlite3.connect('stackoverflow.db')
cur = conn.cursor()
To commit, would I use con.commit(), cur.commit() or are there different times to use each? From the book:
con.commit() :
cur.commit() :
Documentation shows con.commit() :
I took unutbu's advice and tried it myself.
Sample code:
import sqlite3
con = sqlite3.connect('db.db')
cur = con.cursor()
data = [('data', 3), ('data2', 69)]
cur.execute('CREATE TABLE Density(Name TEXT, Number INTEGER)')
for i in data:
cur.execute('INSERT INTO Density VALUES (?, ?)', (i[0], i[1]))
cur.commit()
PyCharm Run:
Traceback (most recent call last):
File "/Users/User/Library/Preferences/PyCharmCE2018.1/scratches/scratch_2.py", line 13, in <module>
cur.commit()
AttributeError: 'sqlite3.Cursor' object has no attribute 'commit'
Error in textbook. cur.commit() does not exist.
Thanks unutbu and s3n0
con.commit() and conn.commit() are the same ... they are created object types ... in both cases they are otherwise named ... important is mainly .commit() and not the naming that the programmer has specified
There are object types that use a different name (con and cur - as you asked) to calling the method. You can also use a different name in your code, for example:
db = sqlite3.connect('/tmp/filename.db')
cursor = db.cursor()
cursor.execute("CREATE TABLE ....
.... some DB-API 2.0 commands ....
")
db.commit()
Please check again the webpage https://docs.python.org/3/library/sqlite3.html .
You forgot to copy these two lines from the webpage:
import sqlite3
conn = sqlite3.connect('example.db')
And then continuing the code (just copied it):
c = conn.cursor()
# Create table
c.execute('''CREATE TABLE stocks
(date text, trans text, symbol text, qty real, price real)''')
# Insert a row of data
c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)")
# Save (commit) the changes
conn.commit()
# We can also close the connection if we are done with it.
# Just be sure any changes have been committed or they will be lost.
conn.close()
I think if you're using a specified cursor to commit changes, in your case, it should be cur.connection.commit().
You can always use connect to commit in the end of your code, whether it's named db, or con or conn.
But when your code gets complicated, you'll have different function to do certain operation to the database, if you only use connection commit, when there is a bug, you gonna have a hard time to find which function failed. So you create specific cursor for specific operation, when that failed, the traceback message will show you which specific cursor when wrong.
To #s3n0 & #DanielYu's point they can be handled two different ways. I had to list these out to better understand the overlap:
Connection Objects
backup
close
commit
create_aggregate
create_collation
create_function
cursor
enable_load_extension
execute
executemany
executescript
in_transaction
interrupt
isolation_level
iterdump
load_extension
rollback
row_factory
set_authorizer
set_progress_handler
set_trace_callback
text_factory
total_changes
Cursor objects
arraysize
close
connection
description
execute
executemany
executescript
fetchall
fetchmany
fetchone
lastrowid
rowcount
setinputsizes
setoutputsize
The code below hangs (even ctrl-C won't stop it, I have to close the terminal) when it tries to create the second table, and I'm not sure why. The first table is created successfully (I can see it in psql with \dt cyanobacteria.*). A simple solution would be to rename the table, but I'm trying to restore someone else's code to working order and I'd have to go through changing lots of stuff. And he had it working once, so it ought to work for me!
I've created a database called 'genomes', a user called 'genomes_admin' and a schema called 'cyanobacteria'. Then I try to make some tables:
#!/usr/bin/python
import psycopg2
psql = "dbname='genomes' user='genomes_admin'"
schm = 'cyanobacteria'
conn = psycopg2.connect(psql)
cur = conn.cursor()
cur.execute('''SET search_path TO %s''', (schm,))
conn.commit()
cur.execute('''CREATE TABLE IF NOT EXISTS testnm(blah text, length int) ''')
print 'created testnm'
conn.commit()
print 'committed'
cur.execute('''CREATE TABLE IF NOT EXISTS genomes(blah text, length int) ''') # hangs here
print 'created genomes' # this line never executes
conn.commit()
print 'committed'
cur.close()
conn.close()