I am currently experimenting with creating and executing stored procedures from Python using SQLAlchemy, and I keep running into this error: "X must be the first statement in a query batch". From reading up on the topic, these "query batches" should be separated by "GO", but "GO" in not supported in SQLAlchemy where I get the following error "Incorrect syntax near 'GO'".
USE my_database;
GO
CREATE PROCEDURE test.test_procedure
AS
SELECT TOP 10 * FROM my_other_database.my_schema.my_table;
# Creating Identical Query
identical_query = """
USE my_database;
GO
CREATE PROCEDURE test.test_procedure
AS
SELECT TOP 10 * FROM my_other_database.my_schema.my_table;
"""
# Creating engine
from sqlalchemy import create_engine
my_engine = create_engine(f"mssql+pyodbc://{self.db_server}/{self.db_name}?trusted_connection=yes&driver={self.db_driver}")
Now let's try to execute the command in various ways as suggested on different forums.
# Execution 1
my_engine.execute(identical_query)
# Execution 2
from sqlalchemy.sql.expression import text
my_engine.execute(text(identical_query))
# Execution 3
with sql_con.db_engine.connect() as con:
query = text(identical_query)
con.execute(query)
None of the ways work, and I just keep getting the error "Incorrect syntax near 'GO'". Shouldn't SQLAlchemy be able to execute the same SQL code that works as is in the SQL database?
As mentioned by @topsail in the comments GO is not an SQL keyword, but it is a keyword unique to "SQL Server Management Studio", where it is used to break queries into batches.
In SQLAlchemy the same functionality can be achieved by breaking up the SQL script by GO, and then using sessions to execute the commands within the same context. See example:
# Imports
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
# Creating a database engine
engine = create_engine("mssql+pyodbc://user:password@server")
# Breaking into batches
q1, q2 = identical_query.split("GO\n")
# create session and add objects
with Session(engine) as session:
session.execute(q1)
session.execute(q2)
session.commit()