Python 创建 SQL 服务器数据库备份文件的脚本(使用 pyodbc)

Python script to create a backup file of a SQL Server database (with pyodbc)

我正在尝试编写 python 脚本来备份 SQL 服务器数据库,然后将其恢复到新数据库中。

SQL 脚本本身在 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)

不知道什么是交易。我在另一个 post 中读到 "con.autocommit = True" 行删除了错误,确实如此。我不知道为什么。

最后,当我 运行 将 con.autocommit 的 python 脚本设置为 True 时,没有抛出任何错误,可以在预期的位置临时看到 BAK 文件('D:/test/test_db.BAK'),但是当脚本完成 运行ning 时,BAK 文件消失了 (???)。有谁知道为什么会这样?

解决方案,如this GitHub issue所述,是在执行完BACKUP语句后,重复调用.nextset() ...

crsr.execute(backup_statement)
while (crsr.nextset()):
    pass

...到"consume" BACKUP 发出的进度消息。如果在连接关闭之前没有使用这些消息,那么 SQL 服务器认为出了点问题并取消备份。

SSMS 显然可以直接捕获这些消息,但是 ODBC 连接必须发出对 ODBC SQLMoreResults 函数的调用以检索每条消息,这就是我们调用 pyodbc .nextset() 方法时发生的情况。