我正在尝试编写一个 python 脚本来备份 SQL Server 数据库,然后将其恢复到新数据库中。
在 SQL Server 中运行时,SQL 脚本本身似乎工作正常:
BACKUP DATABASE TEST_DB
TO DISK = 'D:/test/test_db.BAK';
但是,当我尝试从 python 脚本运行它时,它失败了:
con = pyodbc.connect('UID=xx; PWD=xxxxxx, driver='{SQL Server}', server=r'xxxxxx', database='TEST_DB')
sql_cursor = con.cursor()
query = ("""BACKUP DATABASE TEST_DB
TO DISK = 'D:/test/test_db.BAK';""")
con.autocommit = True
sql_cursor.execute(query1)
con.commit()
首先,如果我不添加“con.autocommit = True”行,它将失败并显示消息:
Cannot perform a backup or restore operation within a transaction. (3021)
不知道什么是交易。我在另一篇文章中读到,“con.autocommit = True”行消除了错误,确实如此。但我不知道为什么。
最后,当我在 con.autocommit 设置为 True 的情况下运行 python 脚本时,不会引发任何错误,可以在预期位置('D:/test/test_db.BAK')暂时看到 BAK 文件,但是当脚本运行完毕,BAK 文件消失(???)。有谁知道为什么会发生这种情况?
最佳答案
解决方案,如 this GitHub issue 中所述,就是执行BACKUP
语句后重复调用.nextset()
...
crsr.execute(backup_statement)
while (crsr.nextset()):
pass
...“消耗”BACKUP
发出的进度消息。如果在连接关闭之前这些消息没有被消耗,那么 SQL Server 就会认为出现了问题并取消备份。
SSMS 显然可以直接捕获这些消息,但 ODBC 连接必须发出对 ODBC SQLMoreResults
函数的调用来检索每条消息,这就是当我们调用 pyodbc .nextset( )
方法。
关于用于创建 SQL Server 数据库备份文件的 Python 脚本(使用 pyodbc),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62119382/