我很好奇为什么我的数据被提交到服务器,因为据我了解,当通过pyodbc
向SQL Server写行时,必须先调用connection.commit()
,然后再将数据提交到服务器。但是,当我在不使用commit()
的情况下运行以下代码时,数据仍然已提交给我的表,并通过以下方式进行了验证:
cursor.execute("SELECT * FROM db.table")
tables = cursor.fetchall()
以及通过SSMS手动检查表格。
这是我用来更新表的代码示例,并认为它不会提交数据,但是会提交数据。
import pyodbc
row_string = 'FIRST_NAME, LAST_NAME, MEMBER_EMAIL, SUPERVISOR_NAME, SUPERVISOR_EMAIL, MEMBER_TITLE'
value_string = [['Name', 'LName', 'Name.LName@randome.com', 'Super Name',
'Super.Name@random.com', 'Some Title']]
ex_value = "insert into DB.TABLE ({}) values (?, ?, ?, ?, ?, ?)".format(row_string)
print(ex_value)
odbc_driver, server, db = '{ODBC Driver 17 for SQL Server}', 'server_address', 'dbname'
# I did try to use this try/except statement provided by Chiheb Nexus below.
# Oddly enough this committed the data but my print statement did not execute.
with pyodbc.connect(driver=odbc_driver, host=server, database=db, trusted_connection='yes') as conn:
try:
conn.autocommit = False
cursor = conn.cursor()
cursor.executemany(ex_value, value_string)
cursor.execute("SELECT * FROM db.TABLE")
tables = cursor.fetchall()
for row in tables:
print('Row: {}'.format(row))
except pyodbc.DatabaseError as err:
conn.rollback()
else:
conn.commit()
finally:
conn.autocommit = True
cursor.close()
结果数据:
insert into db.TABLE (FIRST_NAME, LAST_NAME, MEMBER_EMAIL, SUPERVISOR_NAME, SUPERVISOR_EMAIL, MEMBER_TITLE) values (?, ?, ?, ?, ?, ?)
Row: (9002, 'Name', 'LName', 'Name.LName@randome.com', 'Super Name', 'Super.Name@random.com', 'Some Title', 'None')
Row: (9001, 'Name1 ', 'LName1', 'Name1.LName1@random.com', 'Super Name', 'Super.Name@random.com', 'Some Title', 'None')
如果有人知道(为什么不是奇怪的问题),为什么我的数据以相反的顺序表示呢?我希望我的数据将按照从9001到9002的最高记录进行自上而下的排序,而不是像上面显示的那样反过来。
答案 0 :(得分:1)
就像Pyodbc documentation对于executemany
函数的情况所说的那样:
此外,如果autocommit为True,请多加注意。在这种情况下, SQL语句将提交给数据库中的每个记录 参数序列。因此,如果在处理过程中发生错误, 您最终将获得数据库中提交的一些记录,并且 其余的就不行了,要区分哪些记录可能并不容易 被承诺。因此,您可能需要考虑将autocommit设置为 False(并显式commit()/ rollback())以确保所有 记录已提交到数据库或没有提交
因此,您需要在conn.autocommit = False
之前添加cursor.executemany
,并显式添加conn.commit()
和conn.rollback()
,否则您的更改将被提交到数据库。
这是文档中的一个示例:
try:
cnxn.autocommit = False
params = [ ('A', 1), ('B', 2) ]
cursor.executemany("insert into t(name, id) values (?, ?)", params)
except pyodbc.DatabaseError as err:
cnxn.rollback()
else:
cnxn.commit()
finally:
cnxn.autocommit = True
答案 1 :(得分:0)
如果您需要自己控制交易,则既需要开始交易又要提交/回退。否则,它将不在显式事务模式下,并且SQL Server将每个命令视为一个事务并提交。