How to get the IDENTITY value when using INSERT ... OUTPUT with pyodbc - python

I am trying to get the ID of a newly inserted row by using OUTPUT. However, I encountered the HY010 error. The following query/code is what I use:
string = """
SET NOCOUNT ON;
DECLARE #NEWID TABLE(ID INT);
INSERT INTO dbo.t1 (Username, Age)
OUTPUT inserted.id INTO #NEWID(ID)
VALUES(?, ?)
SELECT ID FROM #NEWID
"""
cursor.execute(string, "John Doe", 35)
cursor.commit()
id = cursor.fetchone()[0]
the last line id = cursor.fetchone()[0] led to a HY010 error (see below). Any advice would be greatly appreciated!
pyodbc.Error: ('HY010', '[HY010] [Microsoft][ODBC SQL Server Driver]Function sequence error (0) (SQLFetch)')

I was able to reproduce your issue, and I was able to avoid it by retrieving the id value immediately after the INSERT and before the commit. That is, instead of
cursor.execute(string, "John Doe", 35)
cursor.commit()
id = cursor.fetchone()[0]
I did
cursor.execute(string, "John Doe", 35)
id = cursor.fetchone()[0] # although cursor.fetchval() would be preferred
cursor.commit()

For me only this worked with Azure SQL Serverless (using pyodbc==4.0.28):
cursor.execute(insert_statement, param_value_list)
cursor.execute("SELECT ##IDENTITY AS ID;")
return cursor.fetchone()[0]

If you're using SQLAlchemy with an engine, then you can retrieve the PyODBC cursor like this before running the query and fetching the table ID.
connection = sql_alchemy_engine.raw_connection()
cursor = connection.cursor()
result = cursor.execute(
"""
INSERT INTO MySchema.MyTable (Col1, Col2) OUTPUT INSERTED.MyTableId
VALUES (?, ?);
""",
col1_value,
col2_value,
)
myTableId = cursor.fetchone()[0]
cursor.commit()
print("my ID is:", myTableId)

Related

Mysql table name getting unwanted quotes resulting table does not exist error

import mysql.connector
def add_features_to_db(stockname, timeframe, date, feature):
try:
conn = mysql.connector.connect(
user='root', password='', host='localhost', database='fx003')
cursor = conn.cursor()
dbtable = stockname + timeframe
mySql_insert_query = """INSERT INTO `%s` (date, trend) VALUES ( `%s`, `%s` )"""
record = (dbtable, date, feature)
cursor.execute(mySql_insert_query, record)
conn.commit()
print("Record inserted successfully")
except mysql.connector.Error as error:
print("Failed to insert into MySQL table {}".format(error))
finally:
if conn.is_connected():
cursor.close()
conn.close()
print("MySQL connection is closed")
add_features_to_db("aud-cad", "_30mins", "2021-09-24 21:00:00", "Short")
I have the code above and giving me the below error:
Failed to insert into MySQL table 1146 (42S02): Table 'fx003.'aud-cad_30mins'' doesn't exist
aud-cad_30mins table does exist and an insert query like below doing its job:
mySql_insert_query = """INSERT INTO aud-cad_30mins (date, trend) VALUES ( "2021-09-24 21:00:00","Short" )"""
So when I try to use variables in the query, it gives the error. Why the table name getting unwanted quotes? Checked several tutorials but couldn't find a solution, any ideas?
The table name should be hardcoded in the query string instead of having it there as a placeholder %s, which is meant for the values to be inserted. So if you have the table name in the variable, you can replace it via format() before calling cursor.execute()
dbtable = stockname + timeframe
mySql_insert_query = """INSERT INTO {} (date, trend) VALUES ( %s, %s )""".format(dbtable)
see the examples in the docs
edit: as Bill mentioned in the comment, dont add the backticks around the %s placeholders.

Get MSSQL autogenerated id from INSERT Statement using SQLAlchemy

I am using SQLAlchemy and MSSQL. I am simply inserting a row and I would like to get back the id of the newly created record.
The SQL query that works with MSSQL and returns the id is:
INSERT INTO [table](...) OUTPUT inserted.ID VALUES (...)
and the alchemy statement I am using is:
with connection() as conn:
query = ...
result_proxy = conn.execute(query)
If you run the query in a sql console, you get back the ID, but I cannot figure out how to get it from the result_proxy returned by the execute statement.
things I have tried and did not work:
result_proxy.lastrowid
result_proxy.last_inserted_id
result_proxy.fetchone()
result_proxy.fetchall()
You are on the right track. I just tried this and it works for me:
import sqlalchemy as sa
# ...
# set up test environment
with engine.begin() as conn:
conn.exec_driver_sql("DROP TABLE IF EXISTS team")
conn.exec_driver_sql(
"CREATE TABLE team ("
"id int identity primary key, "
"prov nvarchar(5), "
"city nvarchar(50), "
"team_name nvarchar(50)"
")"
)
# perform the test
sql = """\
INSERT INTO team (prov, city, team_name)
OUTPUT inserted.id
VALUES (:prov, :city, :team_name)
"""
with engine.begin() as conn:
new_id = conn.execute(
sa.text(sql),
{"prov": "AB", "city": "Calgary", "team_name": "Flames"}
).scalar()
print(new_id) # 1

Create table and insert two records SQL using python

I'm trying to create a table on a tempdb database on a local server KHBW001 using MSSQL. My code is:
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=KHBW001;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
cursor.executemany(
"CREATE TABLE tempdb.dbo.NewTestPyTable(Symbol varchar(15), Shares integer, Price double)") # creates new table
cursor.executemany("""
INSERT INTO tempdb.dbo.NewTestPyTable (Symbol, Shares, Price)
VALUES
[('ETH',55,199.55),
('KHC',66,33.5)]
""") # insert two records into new table
connection.commit()
I'm getting the error:
"CREATE TABLE tempdb.dbo.NewTestPyTable(Symbol varchar(15), Shares
integer, Price double)") # creates new table
TypeError: function takes exactly 2 arguments (1 given)
I don't quite understand what I'm doing wrong. Please assist
Figured it out...
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=KHBW001;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
cursor.execute(
"CREATE TABLE NewTestPyTable(Symbol varchar(15), Shares integer, Price integer)") # creates new table
params = [('ETH', 55, 199),
('KHC', 66, 33)]
# insert two records into new table
cursor.executemany(
"INSERT INTO tempdb.dbo.NewTestPyTable (Symbol, Shares, Price) VALUES (?, ?, ?)", params)
connection.commit()
i think first of all the problem is in table creation
here is the documentation how to create it correctly
https://www.w3schools.com/sql/sql_create_table.asp
type of data in SQL
https://www.journaldev.com/16774/sql-data-types
further it seems to me
you also need to use the money type for the price.
that's how i would do:
import pyodbc
connection = pyodbc.connect('Driver={SQL Server};'
'Server=KHBW001;'
'Database=tempdb;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
cursor.executemany(
"CREATE TABLE tempdb.dbo.NewTestPyTable(Symbol varchar(15), Shares int, Price money)") # creates new table
cursor.executemany("""
INSERT INTO tempdb.dbo.NewTestPyTable (Symbol, Shares, Price)
VALUES
('ETH',55,199.55),
('KHC',66,33.5);
""") # insert two records into new table
connection.commit()

Insert data into MySQL table from Python script

I have a MySQL Table named TBLTEST with two columns ID and qSQL. Each qSQL has SQL queries in it.
I have another table FACTRESTTBL.
There are 10 rows in the table TBLTEST.
For example, On TBLTEST lets take id =4 and qSQL ="select id, city, state from ABC".
How can I insert into the FACTRESTTBL from TBLTEST using python, may be using dictionary?
Thx!
You can use MySQLdb for Python.
Sample code (you'll need to debug it as I have no way of running it here):
#!/usr/bin/python
import MySQLdb
# Open database connection
db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Select qSQL with id=4.
cursor.execute("SELECT qSQL FROM TBLTEST WHERE id = 4")
# Fetch a single row using fetchone() method.
results = cursor.fetchone()
qSQL = results[0]
cursor.execute(qSQL)
# Fetch all the rows in a list of lists.
qSQLresults = cursor.fetchall()
for row in qSQLresults:
id = row[0]
city = row[1]
#SQL query to INSERT a record into the table FACTRESTTBL.
cursor.execute('''INSERT into FACTRESTTBL (id, city)
values (%s, %s)''',
(id, city))
# Commit your changes in the database
db.commit()
# disconnect from server
db.close()

How do I get the "id" after INSERT into MySQL database with Python?

I execute an INSERT INTO statement
cursor.execute("INSERT INTO mytable(height) VALUES(%s)",(height))
and I want to get the primary key.
My table has 2 columns:
id primary, auto increment
height this is the other column.
How do I get the "id", after I just inserted this?
Use cursor.lastrowid to get the last row ID inserted on the cursor object, or connection.insert_id() to get the ID from the last insert on that connection.
Also, cursor.lastrowid (a dbapi/PEP249 extension supported by MySQLdb):
>>> import MySQLdb
>>> connection = MySQLdb.connect(user='root')
>>> cursor = connection.cursor()
>>> cursor.execute('INSERT INTO sometable VALUES (...)')
1L
>>> connection.insert_id()
3L
>>> cursor.lastrowid
3L
>>> cursor.execute('SELECT last_insert_id()')
1L
>>> cursor.fetchone()
(3L,)
>>> cursor.execute('select ##identity')
1L
>>> cursor.fetchone()
(3L,)
cursor.lastrowid is somewhat cheaper than connection.insert_id() and much cheaper than another round trip to MySQL.
Python DBAPI spec also define 'lastrowid' attribute for cursor object, so...
id = cursor.lastrowid
...should work too, and it's per-connection based obviously.
SELECT ##IDENTITY AS 'Identity';
or
SELECT last_insert_id();
This might be just a requirement of PyMySql in Python, but I found that I had to name the exact table that I wanted the ID for:
In:
cnx = pymysql.connect(host='host',
database='db',
user='user',
password='pass')
cursor = cnx.cursor()
update_batch = """insert into batch set type = "%s" , records = %i, started = NOW(); """
second_query = (update_batch % ( "Batch 1", 22 ))
cursor.execute(second_query)
cnx.commit()
batch_id = cursor.execute('select last_insert_id() from batch')
cursor.close()
batch_id
Out:
5
... or whatever the correct Batch_ID value actually is

Categories

Resources