I am using python 2.7 and MySQL as database. In my python program have an INSERT query like this:
cursor.execute("insert into login(username,passw)values('"+i.username+"','"+i.password+"')")
result=cursor.execute("select * from login")
print cursor.fetchall()
When I check in the database, there is no entry. But after the select in my python code, when I print the results it is showing the inserted data. I am not using any transaction statement either.
You need to commit your transaction for the database to make your insert permanent, and you need to use SQL parameters to prevent SQL injection attacks and general quoting bugs:
cursor.execute("insert into login (username, passw) values (%s, %s)", (i.username, i.password))
connection.commit()
Until you commit, the data you inserted will only be visible to your python program; if you do not commit at all, then the changes will be discarded again by the database.
Alternatively, you could switch on auto-commit mode:
connection.autocommit()
After switching on auto-commit, your insertions will be committed instantly. Be careful with this as this could lead to inconsistent data if you need to insert data into multiple rows and / or tables that is interdependent.
You also need to commit the data after your execution statement. It is important to call this method after you are done inserting, or updating data, as the Python connector does not auto commit by default.
# Execute & Commit
cursor.execute("insert into login(username,passw) values('%s','%s')",
i.username, i.password)
# Commit the insert query!
conn.commit()
# Fetch Result
result=cursor.execute("select * from login")
print cursor.fetchall()
If you use mysql-python, you can set connection options to enable autocommit feature.
conn = mysql.connection(host, port, autocommit=True)
# or
conn = mysql.connection(host, port)
conn.autocommit(True)
You can see more details here
Related
I am going to insert data into a table which is in Oracle using by python. It did not give me any error but also it did not insert anything into my table in Oracle SQL Developer. Also I wrote a query to get select rom my table in python environment it gave me output.
My CREATE TABLE code:
cursor = conn.cursor()
cursor.execute("CREATE TABLE INSERT_TEST(FISRT_COLUMN VARCHAR2(30),SECOND_COLUMN NUMBER(10,2))")
My INSERT code:
cursor = conn.cursor()
data = [
('Mina', 20),
('Minoo', 32),
('Sara', 22),
('Ehssan', 25),
('Ladan', 55)
]
for row in data:
cursor.execute("""
insert into INSERT_TEST (FISRT_COLUMN, SECOND_COLUMN)
values (:1, :2)""", row)
My SELECT query:
re = cursor.execute("select * from INSERT_TEST")
for row in re:
print(row)
My output in python environment:
('Mina', 20.0) ('Minoo', 32.0) ('Sara', 22.0) ('Ehssan', 25.0) ('Ladan', 55.0)
My output in Oracle SQL Developer is empty!
I think you need a conn.commit() at the end of your program. commit belongs to the connection class, not to the cursor.
I understand it depends on table in oracle SQL developer, a the end of my code I have to write cursor.execute('commit') to show that it end and insert all of the data into my table.
Check the documentation for your database driver.
For some database drivers, the default behaviour is to COMMIT any uncommitted data when you close the transaction and the connection; so, make sure you close the connection when you have finished.
For other database drivers, the default behaviour is to ROLLBACK any uncommitted data when you close the transaction and the connection; in this case, you will need to explicitly COMMIT the data before you close the connection otherwise it will ROLLBACK your changes.
The Oracle database does not let other sessions (even belonging to the same user) see uncommitted data so, if you INSERT from Python but do not COMMIT (either explicitly or, if the driver supports it, implicitly when you close the connection) then you will be able to see it from the Python session where you created the data but it will be hidden when you view it in another session (i.e. from SQL Developer).
I use a MS SQL express db. I can connect and fetch data. But inserting data does not work:
cursor.execute("insert into [mydb].[dbo].[ConvertToolLog] ([Message]) values('test')")
I get no error but nothing is inserted into the table.
Directly after I fetch the data the inserted row is fetched. But nothing is saved.
In MS SQL Server Management Studio the insertion does work.
You need to commit the data. Each SQL command is in a transaction and the transaction must be committed to write the transaction to the SQL Server so that it can be read by other SQL commands.
Under MS SQL Server Management Studio the default is to allow auto-commit which means each SQL command immediately works and you cannot rollback.
The example is from pyodbc Getting Started document
First opening the database and set up a cursor
import pyodbc
# Specifying the ODBC driver, server name, database, etc. directly
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass')
# Create a cursor from the connection
cursor = cnxn.cursor()
The insert example in the document is then
# Do the insert
cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
#commit the transaction
cnxn.commit()
or better using parameters
cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
cnxn.commit()
As the document says
Note the calls to cnxn.commit(). You must call commit or your changes will be lost! When the connection is closed, any pending changes will be rolled back. This makes error recovery very easy, but you must remember to call commit.
Same issue here, slight modification to answers above. I struggled with this for a while, realized the SQL was running but not committing. My environment is Python 3.8.2, MSSQL Server Express 15.0.2070.41 (2019). I had to use cursor.commit(), and it worked as expected.
import pyodbc
# cnxn info is in a text file so I can change it in one place
def cnxn():
f=open("sql_conn.csv")
sql_split=f.read().split(",")
server=sql_split[0]
database=sql_split[1]
uid=sql_split[2]
pwd=sql_split[3]
return pyodbc.connect('DRIVER={ODBC Driver 17 for SQL
Server};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (server,database,uid,pwd))
# sql statement is passed by .py script
def f_sql_insert(sql):
cursor = cnxn().cursor()
cursor.execute(sql)
cursor.commit()
cnxn().close()
I'm connecting mysql on my Kivy application.
import mysql.connector
con = mysql.connector.Connect(host='XXX', port=XXX, user='XXX', password='XXX', database='XXX')
cur = con.cursor()
db = cur.execute("""select SELECT SQL_NO_CACHE * from abc""")
data = cur.fetchall()
print (data)
After inserting or deleting on table abc from another connection; i call the same query on python; but data is not updating.
I add the query "SET SESSION query_cache_type = OFF;" before select query, but it didn't work. Someone said "select NOW() ..." query is not cachable but it didn't work again. What should I do?
I solved this by adding the code after fetchall()
con.commit()
Calling the same select query without doing a commit, won't update the results.
The solution is to use:
Once:
con.autocommit(True)
Or, after each select query:
con.commit()
With this option, there will be a commit after each select query.
Otherwise, subsequent selects will render the same result.
This error seems to be Bug #42197 related to Query cache and auto-commit in MySQL. The status is won't fix!
In a few months, this should be irrelevant because MySQL 8.0 is dropping Query Cache.
I encounterd the same problem that has been solved and used the above method.
conn.commit()
and I found that different DBMS has different behavior,not all DBMS exist in the connection cache
try this,
conn.autocommit(True);
this will auto commit after each of you select query.
The MySQL query cache is flushed when tables are modified, so it wouldn't have that effect. It's impossible to say without seeing the rest of your code, but it's most likely that your INSERT / DELETE query is failing to run.
I use a MS SQL express db. I can connect and fetch data. But inserting data does not work:
cursor.execute("insert into [mydb].[dbo].[ConvertToolLog] ([Message]) values('test')")
I get no error but nothing is inserted into the table.
Directly after I fetch the data the inserted row is fetched. But nothing is saved.
In MS SQL Server Management Studio the insertion does work.
You need to commit the data. Each SQL command is in a transaction and the transaction must be committed to write the transaction to the SQL Server so that it can be read by other SQL commands.
Under MS SQL Server Management Studio the default is to allow auto-commit which means each SQL command immediately works and you cannot rollback.
The example is from pyodbc Getting Started document
First opening the database and set up a cursor
import pyodbc
# Specifying the ODBC driver, server name, database, etc. directly
cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=testdb;UID=me;PWD=pass')
# Create a cursor from the connection
cursor = cnxn.cursor()
The insert example in the document is then
# Do the insert
cursor.execute("insert into products(id, name) values ('pyodbc', 'awesome library')")
#commit the transaction
cnxn.commit()
or better using parameters
cursor.execute("insert into products(id, name) values (?, ?)", 'pyodbc', 'awesome library')
cnxn.commit()
As the document says
Note the calls to cnxn.commit(). You must call commit or your changes will be lost! When the connection is closed, any pending changes will be rolled back. This makes error recovery very easy, but you must remember to call commit.
Same issue here, slight modification to answers above. I struggled with this for a while, realized the SQL was running but not committing. My environment is Python 3.8.2, MSSQL Server Express 15.0.2070.41 (2019). I had to use cursor.commit(), and it worked as expected.
import pyodbc
# cnxn info is in a text file so I can change it in one place
def cnxn():
f=open("sql_conn.csv")
sql_split=f.read().split(",")
server=sql_split[0]
database=sql_split[1]
uid=sql_split[2]
pwd=sql_split[3]
return pyodbc.connect('DRIVER={ODBC Driver 17 for SQL
Server};SERVER=%s;DATABASE=%s;UID=%s;PWD=%s' % (server,database,uid,pwd))
# sql statement is passed by .py script
def f_sql_insert(sql):
cursor = cnxn().cursor()
cursor.execute(sql)
cursor.commit()
cnxn().close()
I have done the following:
import MySQLdb as mdb
con = mdb.connect(hostname, username, password, dbname)
cur = con.cursor()
count = cur.execute(query)
cur.close()
con.close()
I have two queries, I execute them in the mysql console I can view the results.
But when I give the same through python one query works and the other one does not.
I am sure it is not problem with mysql or query or python code. I suspect cur.execute(query) function.
Have anyone come through similar situation? Any solutions?
Use conn.commit() after execution, to commit/finish insertion and deletion based changes.
I have two queries, I execute them in the mysql console I can view the results.
But I only see one query:
import MySQLdb as mdb
con = mdb.connect(hostname, username, password, dbname)
cur = con.cursor()
count = cur.execute(query)
cur.close()
con.close()
My guess is query contains the both queries separated by a semin-colon and is an INSERT statement? You probably need to use executemany().
See Executing several SQL queries with MySQLdb
On the other hand, if both of your queries are SELECT statements (you say "I see the result"), I'm not sure you can fetch both results from only one call to execute(). I would consider that as bad style, anyway.
This is a function and the query is passed to this function. When I
execute one query after the other. I dont get the result for few
queries, there is no problem with the queries because I have crossed
checked them with the mysql console.
As you clarified your question in a comment, I post an other answer -- completely different approach.
Are you connected to your DB in autocommit mode? If no, for changes to be permanently applied, you have to COMMIT them. In normal circumstances, you shouldn't create a new connection for each request. That put excessive load on the DB server for almost nothing:
# Open a connection once
con = mdb.connect(hostname, username, password, dbname)
# Do that *for each query*:
cur = con.cursor()
try:
count = cur.execute(query)
conn.commit() # don't forget to commit the transaction
else:
print "DONE:", query # for "debug" -- in real app you migth have an "except:" clause instead
finally:
cur.close() # close anyway
# Do that *for each query*:
cur = con.cursor()
try:
count = cur.execute(query)
conn.commit() # don't forget to commit the transaction
else:
print "DONE:", query # for "debug" -- in real app you migth have an "except:" clause instead
finally:
cur.close() # close anyway
# Close *the* connection
con.close()
The above code is directly typed into SO. Please forgive typos and other basic syntax errors. But that's the spirit of it.
A last word, while typing I was wondering how you deal with exceptions? By any chance could the MySQLdb error be silently ignored at some upper level of your program?
Use this query, this will update multiple rows of column in one query
sql=cursor.executemany("UPDATE `table` SET `col1` = %s WHERE `col2` = %s",
[(col1_val1, col2_val1),(col2_val2, col_val2)])
and also commit with database to see the changes.
conn.commit()