I am writing a python script that does the following as a part a transaction.
Creates a new database.
Creates new tables using a schema.sql file.
Copies the data from the master DB to this new DB using insert into select * from master.table_name... like SQL statements.
Commits the txn, in the else block, if everything goes right. Rollback the txn, in the except block, if something goes wrong.
Close the connection in the finally block.
However, while testing, I found out that rollback isn't working. If an exception is raised after DB is created, even after rollback, DB is created. If an exception is raised after inserting data into a few tables with some tables remaining, calling rollback in the except block does not revert the inserted data. The script looks like this:
import mysql.connector
try:
conn = mysql.connector.connect(host='localhost', port=3306,
user=USERNAME, password=PASSWORD,
autocommit=False)
cursor.execute("START TRANSACTION;")
cursor.execute(f"DROP DATABASE IF EXISTS {target_db_name};")
cursor.execute(f"CREATE DATABASE {target_db_name};")
cursor.execute(f"USE {target_db_name};")
with open(SCHEMA_LOCATION) as f:
schema_query = f.read()
commands = schema_query.split(";")
for command in commands:
cursor.execute(command)
for query in QUERIES:
cursor.execute(f"{query}{org_Id};")
except Exception as error:
conn.rollback()
else:
conn.commit() # cursor.execute("COMMIT")
finally:
if conn.is_connected():
cursor.close()
conn.close()
Below are the details of the setup
Python3
mysql-connector-python==8.0.32
MySQL 5.7
Storage Engine: InnoDB
I made a website with flask which connect to a db file with sqlite3. When i run it locally it functions, but when I host it on vercel, the log shows no error but the db never commit and save any changes.
#example of a update
with sqlite3.connect(db) as connection:
try:
connection.execute("UPDATE Survey SET Responders = Survey.Responders+1 WHERE SurveyID = ?",(data["id"],))
connection.commit()
print("response added")
except Error as e:
print(e)
The database never save any changes, although i can select from the connection normally
I am writing and reading from a sql database with tries & excepts. The thought behind the try/except is if for some reason the internet is down or we cannot connect to the server, we will write the sql transactions locally to a text file and then use those statements to update the table. That being said - the try and except only seems to work if there is a connection to the server. We have a table BAR in the DB database on server FOO:
try:
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=FOO;DATABASE=DB;UID=user;PWD=password')
cursor = conn.cursor()
cursor.execute("UPDATE BAR SET Date = '"+time+"' WHERE ID = "+ID)
conn.commit()
except:
f = open("vistorlog.txt", "a")
f.write("UPDATE BAR SET Date = '"+time+"' WHERE ID = "+ID+"\n")
f.close()
the only instance where this try&except works is when there is an issue with the sql statement i.e. "Update BARS..." fails because there is no table named BARS. If I change the server to FOOS (or in a real life scenario unplug the ethernet cord and leave the table/serve names legitimate) the try and except doesn't work - the program freezes with no error.
I want to make a python script that consistently checks the Mysql database.
The problem that is arising is that the first time checks that there is no data it consistently says there is no data in the database even after I add the data in the database.
But if the data is already there in the database I immediately fetch it and continues.
What can I do such that my python script consistently checks the database and if it finds the data it stops checking the database and continue's
I have tried running it when there is no data in the database and then added data to the database
import mysql.connector
mydb = mysql.connector.connect(
host='localhost',
user='root',
passwd='',
database='local_data'
)
mycursor = mydb.cursor()
node_id = 123
node_id = str(node_id)
print('getting code...')
a = 0
while True:
try:
time.sleep(1)
a=a+1
print(a)
sql = "SELECT code_name FROM node_code where node_id = '"+node_id +"'"
mycursor.execute(sql)
myresult = mycursor.fetchone()
for x in myresult:
filename=x
print(filename)
break
except Exception as error:
print("Nothing in database\n")
print(error)
I am expecting an output where it keeps checking the database until it finds the data after which it continues
I am getting these results. By the time the second loop ran the data was inserted in the database
getting code...
1
Nothing in database
'NoneType' object is not iterable
2
Nothing in database
'NoneType' object is not iterable
3
Nothing in database
If the data is already in the database before I run the script I get this
getting code...
1
server.py
This is because the transaction has not ended unless you do a commit to end that transaction.
Try committing that transaction by doing mycursor.commit() at the end of loop
I'm writing a python script to monitor a few 1wire sensors off of a Raspberry Pi and store the results in a MySQL database.
Using the MySQL Connector/Python library I can successfully connect to the database, and run the query however the transaction doesn't seem to fully commit. I know the query runs successfully since the out param is set to the new auto-incremented ID.
CREATE TABLE `lamp`.`sensors` (
`SensorID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`SensorSerial` char(15) NOT NULL,
`SensorFamily` tinyint(4) NOT NULL,
PRIMARY KEY (`SensorID`),
UNIQUE KEY `SensorID_UNIQUE` (`SensorID`),
UNIQUE KEY `SensorSerial_UNIQUE` (`SensorSerial`)
)
CREATE PROCEDURE `lamp`.`AddSensor` (sensorSerial char(15),
sensorFamily tinyint, out returnValue int)
BEGIN
INSERT INTO sensors (SensorSerial,SensorFamily) VALUES (sensorSerial,sensorFamily);
SET returnValue=LAST_INSERT_ID();
END
However when I attempt to query the table (Select * from sensors) I get 0 results. If I run the procedure from the MySQL Workbench or from a .Net application everything works as expected. Which means I'm missing something when it comes to the Connector/Python, but I have no clue what. I'm extremely baffled since the auto-increment value does increase but no records are added. There are also no errors reported
def Test(self):
#this line works fine
#self.RunProcedure("INSERT INTO sensors (SensorSerial,SensorFamily) VALUES ('{0}',{1})".format(self.ID,self.Family),False,())
#this line does not?
args=self.RunProcedure('AddSensor',True,(self.ID,self.Family,-1))
if args[2]>=1:
logging.debug("Successfully added sensor data '{1}' for sensor '{0}' to the database".format(self.ID,value))
return True
else:
logging.critical("Failed to add Data to Database for unknown reason. SensorID: {0} Type: {1} Data:{2}".format(self.ID,self.Family,value))
def RunProcedure(self,proc,isStored,args):
try:
logging.debug("Attempting to connect to database.")
connection=mysql.connector.connect(user='root',password='1q2w3e4r',host='localhost',database='LAMP')
except mysql.connector.Error as e:
logging.exception("Failed to connect to mysql database.\r\n {0}".format(e))
else:
logging.debug("Successfully connected to database.")
try:
cursor=connection.cursor()
if isStored:
args = cursor.callproc(proc,args)
return args
else:
cursor.execute(proc,args)
#these do not seem to solve the issue.
#cursor.execute("Commit;")
#connection.commit()
except mysql.connector.Error as e:
logging.exception("Exception while running the command '{0}' with the args of '{1}' exception is {2}".format(proc,args,e))
finally:
logging.debug("Closing connection to database")
cursor.close()
connection.close()
Output from to the log looks like this;
2013-06-09 13:21:25,662 Attempting to connect to database.
2013-06-09 13:21:25,704 Successfully connected to database.
2013-06-09 13:21:25,720 Closing connection to database
2013-06-09 13:21:25,723 Successfully added sensor data '22.25' for sensor '10.85FDA8020800' to the database
**Edit
Not sure why but adding autocommit=True to the connection.open params seems to have resolved the issue. Since it was a problem with committing why didn't connection.commit() or the cursor.execute('commit;') correct the issue?
The problem is actually in your code:
..
try:
cursor=connection.cursor()
if isStored:
args = cursor.callproc(proc,args)
return args
else:
cursor.execute(proc,args)
connection.commit()
except mysql.connector.Error as e:
..
If you are using the Stored Routine, you are immediately returning, so commit() will never be called.