Bug #78308 | Executing several statements is "allowed" by default | ||
---|---|---|---|
Submitted: | 2 Sep 2015 18:09 | Modified: | 11 Jan 2023 20:21 |
Reporter: | Sebastien Celles | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | Connector / Python | Severity: | S3 (Non-critical) |
Version: | 2.0.4 | OS: | Any |
Assigned to: | CPU Architecture: | Any |
[2 Sep 2015 18:09]
Sebastien Celles
[3 Sep 2015 8:09]
MySQL Verification Team
Hello Sebastien Celles, Thank you for the report. Thanks, Umesh
[11 Jan 2023 20:21]
Oscar Pacheco
Posted by developer: Hello Sebastien, After analyzing the report carefully, I found there isn't a bug from connector-python. SQLAlchemy does not support multi-query/command statements based on my research, and even if it does, the problem does not come from connector-python (see script below). Regarding connector-python, I created an example very similar to the one you provided, I see no issues. --------- bug78308.py (python script) --------- """ $ pip list Package Version ---------------------- ------- mysql-connector-python 8.0.31 numpy 1.24.1 pandas 1.5.2 SQLAlchemy 1.4.46 """ import os import sqlalchemy import pandas as pd import numpy as np import mysql.connector password = os.environ.get("mypass") db_uri = f"mysql+mysqlconnector://root:{password}@localhost:3306/test" engine = sqlalchemy.create_engine(db_uri, connect_args={"use_pure": True}) with engine.connect() as cnx: df = pd.DataFrame(np.random.randn(4, 3), columns=["a", "b", "c"]) df.to_sql("df", con=cnx, if_exists="replace") df.to_sql("test_table", con=cnx, if_exists="replace") """ This code block works fine """ # res = pd.read_sql("SELECT * from df where a>0", con=cnx) # print(res) """ This code block fails with error: sqlalchemy.exc.InterfaceError: (mysql.connector.errors.InterfaceError) Use multi=True when executing multiple statements [SQL: SELECT * from df where a>0; SELECT @@version] because SQLAlchemy does not support multi-query/command statements. """ # res = pd.read_sql("SELECT * from df where a>0; SELECT @@version", con=cnx) # print(res) config = { "username": "root", "password": password, "use_pure": True, "port": 3306, "database": "test", } with mysql.connector.connect(**config) as cnx: with cnx.cursor() as cur: cur.execute("SELECT * from df where a>0") single_query_res_1 = cur.fetchall() cur.execute("SELECT @@version") single_query_res_2 = cur.fetchall() """ for recent versions of connector python, multi=False by default """ try: multi_query_res = [ res_cursor.fetchall() for res_cursor in cur.execute( "SELECT * from df where a>0; SELECT @@version; DROP TABLE test_table; DROP TABLE df", multi=True, ) ] except mysql.connector.errors.InterfaceError: print("Bug report confirmed!") else: if multi_query_res[:2] == [single_query_res_1, single_query_res_2]: print( "Execute with multi=True is working!" ) --------- Terminal --------- $ python bug78308.py Execute with multi=True is working! Finally, after taking a look at the MySQL console I found both tables `df` and `test_table` were dropped successfully. --------- MySQL Console --------- mysql> USE test; mysql> SHOW TABLES; Empty set (0.00 sec)
[11 Jan 2023 20:23]
Oscar Pacheco
Posted by developer: Hello Sebastien, After analyzing the report carefully, I found there isn't a bug from connector-python. SQLAlchemy does not support multi-query/command statements based on my research, and even if it does, the problem does not come from connector-python (see script below). Regarding connector-python, I created an example very similar to the one you provided, I see no issues. --------- bug78308.py (python script) --------- """ $ pip list Package Version ---------------------- ------- mysql-connector-python 8.0.31 numpy 1.24.1 pandas 1.5.2 SQLAlchemy 1.4.46 """ import os import sqlalchemy import pandas as pd import numpy as np import mysql.connector password = os.environ.get("mypass") db_uri = f"mysql+mysqlconnector://root:{password}@localhost:3306/test" engine = sqlalchemy.create_engine(db_uri, connect_args={"use_pure": True}) with engine.connect() as cnx: df = pd.DataFrame(np.random.randn(4, 3), columns=["a", "b", "c"]) df.to_sql("df", con=cnx, if_exists="replace") df.to_sql("test_table", con=cnx, if_exists="replace") """ This code block works fine """ # res = pd.read_sql("SELECT * from df where a>0", con=cnx) # print(res) """ This code block fails with error: sqlalchemy.exc.InterfaceError: (mysql.connector.errors.InterfaceError) Use multi=True when executing multiple statements [SQL: SELECT * from df where a>0; SELECT @@version] because SQLAlchemy does not support multi-query/command statements. """ # res = pd.read_sql("SELECT * from df where a>0; SELECT @@version", con=cnx) # print(res) config = { "username": "root", "password": password, "use_pure": True, "port": 3306, "database": "test", } with mysql.connector.connect(**config) as cnx: with cnx.cursor() as cur: cur.execute("SELECT * from df where a>0") single_query_res_1 = cur.fetchall() cur.execute("SELECT @@version") single_query_res_2 = cur.fetchall() """ for recent versions of connector python, multi=False by default """ try: multi_query_res = [ res_cursor.fetchall() for res_cursor in cur.execute( "SELECT * from df where a>0; SELECT @@version; DROP TABLE test_table; DROP TABLE df", multi=True, ) ] except mysql.connector.errors.InterfaceError: print("Bug report confirmed!") else: if multi_query_res[:2] == [single_query_res_1, single_query_res_2]: print( "Execute with multi=True is working!" ) --------- Terminal --------- $ python bug78308.py Execute with multi=True is working! Finally, after taking a look at the MySQL console I found both tables `df` and `test_table` were dropped successfully. --------- MySQL Console --------- mysql> USE test; mysql> SHOW TABLES; Empty set (0.00 sec)
[11 Jan 2023 20:23]
Oscar Pacheco
Posted by developer: Hello Sebastien, After analyzing the report carefully, I found there isn't a bug from connector-python. SQLAlchemy does not support multi-query/command statements based on my research, and even if it does, the problem does not come from connector-python (see script below). Regarding connector-python, I created an example very similar to the one you provided, I see no issues. --------- bug78308.py (python script) --------- """ $ pip list Package Version ---------------------- ------- mysql-connector-python 8.0.31 numpy 1.24.1 pandas 1.5.2 SQLAlchemy 1.4.46 """ import os import sqlalchemy import pandas as pd import numpy as np import mysql.connector password = os.environ.get("mypass") db_uri = f"mysql+mysqlconnector://root:{password}@localhost:3306/test" engine = sqlalchemy.create_engine(db_uri, connect_args={"use_pure": True}) with engine.connect() as cnx: df = pd.DataFrame(np.random.randn(4, 3), columns=["a", "b", "c"]) df.to_sql("df", con=cnx, if_exists="replace") df.to_sql("test_table", con=cnx, if_exists="replace") """ This code block works fine """ # res = pd.read_sql("SELECT * from df where a>0", con=cnx) # print(res) """ This code block fails with error: sqlalchemy.exc.InterfaceError: (mysql.connector.errors.InterfaceError) Use multi=True when executing multiple statements [SQL: SELECT * from df where a>0; SELECT @@version] because SQLAlchemy does not support multi-query/command statements. """ # res = pd.read_sql("SELECT * from df where a>0; SELECT @@version", con=cnx) # print(res) config = { "username": "root", "password": password, "use_pure": True, "port": 3306, "database": "test", } with mysql.connector.connect(**config) as cnx: with cnx.cursor() as cur: cur.execute("SELECT * from df where a>0") single_query_res_1 = cur.fetchall() cur.execute("SELECT @@version") single_query_res_2 = cur.fetchall() """ for recent versions of connector python, multi=False by default """ try: multi_query_res = [ res_cursor.fetchall() for res_cursor in cur.execute( "SELECT * from df where a>0; SELECT @@version; DROP TABLE test_table; DROP TABLE df", multi=True, ) ] except mysql.connector.errors.InterfaceError: print("Bug report confirmed!") else: if multi_query_res[:2] == [single_query_res_1, single_query_res_2]: print( "Execute with multi=True is working!" ) --------- Terminal --------- $ python bug78308.py Execute with multi=True is working! Finally, after taking a look at the MySQL console I found both tables `df` and `test_table` were dropped successfully. --------- MySQL Console --------- mysql> USE test; mysql> SHOW TABLES; Empty set (0.00 sec)