Executing Mysql stored procedure using python - python

I have a stored procedure statement that doesnt execute when using mysql cursor in python, but it executes on any other Mysql query Tools such as workbench or navicat. I have successfuly connected to my database that contains a table called users.
import mysql.connector
from mysql.connector import Error
mydb = mysql.connector.connect(
host="localhost",
user="root",
password="root",
charset='utf8',
database="story_db"
)
mycursor = mydb.cursor()
query="DELIMITER $$ CREATE PROCEDURE GetAllUsers() BEGIN SELECT * FROM users; END $$
DELIMITER ;"
try:
mycursor.execute(query)
print("success")
except Error as err:
print(err)
I get this error as a result:
1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER $$ CREATE PROCEDURE GetAllUsers() BEGIN SELECT * FROM users' at line 1

DELIMITER is command-line client's command, not SQL statement. Do not use it in SQL code.
In your particular case the stored procedure contains ONE SQL-statement, so it may be created without BEGIN-END block, using single statement, and does not need in DELIMITER reassign even in CLI. I.e. simply
CREATE PROCEDURE GetAllUsers()
SELECT * FROM users;

Related

update statement under pyodbc issue

I am currently developing a program in python that interacts with multiple database. I am using pyodbc to connect, and execute queries. One of the database is an azure database. I noticed sometimes the sent data is not updated in the database although the program run successfully and no error was thrown. Is there any practices that i should follow to make sure this doesn't happen or is this related to my code or db connection issue? I am a beginner. Would appreciate everyone's help thank you!
Also is the .commit() line should be run after every sql run?
The program should be updating a row of data in the database based on a condition, this particular query sometimes doesn't take effect, but no error was thrown. I also executed multiple queries after that, no issue was found for the next queries. It is successfully executed.
the query is a simple query which is
UPDATE DraftVReg SET VRStatus = 'Potential Duplicate Found' WHERE RowID = ?
I tried to reproduce your scenario on my end and was able to update the SQL row in the Azure SQL DB with Pyodbc module.
Yes, Its very necessary to use
conn.commit
to commit your changes inside a database after you perform operations such as Update or Insert inside Azure SQL DB programmatically.
1) Fetch Data with Select statement.
I was able to fetch the Table’s data successfully with Select * from ‘Tablename’ query inside pyodbc code before I try UPDATE statement.
import pyodbc
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};''SERVER=tcp:sqlservernamesql.database.windows.net,1433;''DATABASE=databasename; UID=siliconuser;PWD=Password;')
#conn.commit()
cursor = conn.cursor()
cursor.execute('Select * FROM StudentReviews')
#conn.commit()
for i in cursor:
print(i)
cursor.close()
conn.close()
Result:-
2) UPDATE the rows require conn.commit()
Code :-
import pyodbc
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};''SERVER=tcp:siliconserversql.database.windows.net,1433;''DATABASE=silicondb; UID=userid; PWD=Password;')
cursor = conn.cursor()
#cursor.execute('Select * FROM StudentReviews')
cursor.execute("UPDATE StudentReviews SET ReviewTime = ('7') WHERE ReviewText = ('SQL DB')")
conn.commit()
cursor.close()
conn.close()
Result:-
Update statement Executed successfully and the Table Row was updated in Azure SQL, Refer Below :-
3) With autocommit=true
Thank you #Gord thompson for the comment and suggestion!
Code :-
import pyodbc
conn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};''SERVER=tcp:siliconserversql.database.windows.net,1433;''DATABASE=silicondb; UID=username; PWD=Password;', autocommit=True)
#conn.commit()
cursor = conn.cursor()
cursor.execute("UPDATE StudentReviews SET ReviewTime = ('8') WHERE ReviewText = ('SQL DB')")
cursor.close()
conn.close()
Results :- With autocommit=true, You do not need to add conn.commit everytime you update the SQL DB.

python pyodbc: Closing the cursor before conn.commit()?

I have an issue with inserting data into a database using the python package pyodbc and since I am pretty new to pyodbc & databases in general, I might lack some basic understanding.
I open a connection, and then I want the execute my query.
Actually, in this query I call a stored procedure (which I didn't write and I am not allowed to change!).
This procedure does "one or two" inserts. When I use pyodbc like this
conn = pyodbc.connect(connection_string)
with conn:
c = conn.cursor()
c.execute("{call input_procedure('some','parameters','to','insert')}")
OR
conn = pyodbc.connect(connection_string)
c = conn.cursor()
c.execute("{call input_procedure('some','parameters','to','insert')}")
conn.commit()
I get the following error message:
pyodbc.Error: ('HY000', "[HY000] [MySQL][ODBC 8.0(a) Driver]Commands out of sync; you can't run this command now (2014) (SQLEndTran(SQL_COMMIT))")
As far as I understood, this error message might be due to executing more than one insert within the called procedure. When I print the return of the execute command I become the following: (' ', )
When I instead close the cursor, before doing the commit, everything works fine. Like this:
conn = pyodbc.connect(connection_string)
c = conn.cursor()
c.execute("{call input_procedure('some','parameters','to','insert')}")
c.close()
conn.commit()
I really don't understand what's happening here.
Is there an explanation for this behaviour? Is closing the cursor before doing the commit save?
Thanks a lot for your help!
You seem to have encountered a quirk in MySQL Connector/ODBC's handling of result sets from a stored procedure. For this example procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `input_procedure`(IN `p1` VARCHAR(50))
MODIFIES SQL DATA
BEGIN
INSERT INTO table1 (txt) VALUES (p1);
SELECT '' AS foo;
END
this Python code
crsr = cnxn.cursor()
crsr.execute("{call input_procedure('thing')}")
cnxn.commit()
throws the "Commands out of sync" error, whereas this code
crsr = cnxn.cursor()
crsr.execute("{call input_procedure('thing')}")
while crsr.nextset():
pass
cnxn.commit()
does not.

How to commit stored procedure execution by using pyodbc

I am trying to execute stored procedure by using pyodbc in databricks, after executing SP I tried to commit the connection but, commit is not happening. Here I am giving my code, please help me out from this issue.
import pyodbc
#### Connecting Azure SQL
def db_connection():
try:
username = "starsusername"
password = "password-db"
server = "server-name"
database_name = "db-name2"
port = "db-port"
conn=pyodbc.connect('Driver={ODBC Driver 17 for SQL server};SERVER=tcp:'+server+','+port+';DATABASE='+ database_name +';UID='+ username +';PWD='+ password)
cursor=conn.cursor()
return cursor, conn
except Exception as e:
print("Faild to Connect AZURE SQL: \n"+str(e))
cursor, conn = db_connection()
# conn1.autocommit=True
cursor.execute("delete from db.table_name")
cursor.execute("insert into db.table_name(BUSINESS_DATE) values('2021-10-02')")
cursor.execute("exec db.SP_NAME '20211023'")
conn.commit()
conn.close()
here I am commiting connection after SP excution. deletion and insertion is not happening at all. and I tried with cursor.execute("SET NOCOUNT ON; exec db.SP_NAME '20211023'") but it's also not working.
Thanks in Advance
If you check this document on pyodbc, you will find that -
To call a stored procedure right now, pass the call to the execute method using either a format your database recognizes or using the ODBC call escape format. The ODBC driver will then reformat the call for you to match the given database.
Note that after connection is set up or done, try doing conn.autocommit = True before calling your SP and it will help. By default it is false.
Executing the Stored Procedure.
You will be able to execute your stored procedure if you follow the below code snippet.
cursor = conn.cursor()
conn.autocommit = True
executesp = """EXEC yourstoredprocedure """
cursor.execute(executesp)
conn.commit()
Delete the Records in SQL Server
You can delete record as shown in the below example.
...#just an example
cursor.execute('''
DELETE FROM product
WHERE product_id in (5,6)
''')
conn.commit()
Don’t forget to add conn.commit() at the end of the code, to ensure that the command would get executed.
Insert record in SQL Server
The below snippet show how we can do the same.
...#just an example
cursor.execute("INSERT INTO EMP (EMPNO, ENAME, JOB, MGR) VALUES (535, 'Scott', 'Manager', 545)")
conn.commit()
I will suggest you to read the for following document for more information.
Delete Record Documentation.
Insert Record Document

ProgrammingError 1064 doing CREATE TABLE AS SELECT from an existing table with MySQL in Python

I have an existing table in the cloud and I want to make a copy of it. I connect to my database via pymysql, extract the username from an input provided from the new user, and I want to create a new table that will be called by the username, and that table will be a copy of the original one. When I run the code below, I have the following error:
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''username' AS SELECT * FROM original_table' at line 1")
uname = blabla#bla.com
conn = pymysql.connect(
host="db.host",
port=int(3306),
user=user,
passwd=password,
db=db,
charset='utf8mb4'
)
cur = conn.cursor()
table_name = uname.replace('#', '_').replace('.', '_')
print('TABLE NAME:', table_name)
cur.execute(""" CREATE TABLE %s AS SELECT * FROM original_table """, (table_name))
Parameter quoting is for quoting values. Quoting table names does not work, because in MySQL the way to quote a table name is by using backticks (`), not quotation marks.
MariaDB [test]> CREATE TABLE 'username' AS SELECT * FROM my_table;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''username' AS SELECT * FROM my_table' at line 1
In this cause you need to use string formatting to create the SQL statement (you can use backticks to defend against SQL-injection*):
cur.execute(""" CREATE TABLE `%s` AS SELECT * FROM original_table """ % table_name)
* I'm not an expert on SQL-injection, so do some research if table_name originates outside your application.

Can't insert PDF file into MySQL db with Python

I'm stuck. I've been trying to insert a pdf file in to MySQL db but I can't. I've tried with mysql.connector and MySQLdb classes. I get nearly the same errors. I've read many posts about this issue. I tried commas, variables also. Here are my code and error;
import mysql.connector
db = mysql.connector.connect(host="127.0.0.1", user='root', password='masatablo', db='yukleme')
c = db.cursor()
acilacak_dosya = open("bizim.PDF", "rb")
yuklenecek_dosya = acilacak_dosya.read()
c.execute ("INSERT INTO pdfler (cizim) VALUES(%s)" %(yuklenecek_dosya))
db.commit()
db.close()
ERROR with mysql.connector:
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b'%PDF-1.4\r%\xe2\xe3\xcf\xd3\r\n4 0 obj\r<</Linearized 1/L 83892/O 6/E 79669/N ' at line 1
ERROR with MySQLdb:
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'b'%PDF-1.4\\r%\\xe2\\xe3\\xcf\\xd3\\r\\n4 0 obj\\r<</Linearized 1/L 83892/O 6/E 79669/N ' at line 1")
You'll need to use parameters, not string interpolation.
String interpolation with SQL is vulnerable to SQL injection attacks anyway.
c.execute("INSERT INTO pdfler (cizim) VALUES (%s)", (yuklenecek_dosya,))

Categories

Resources