我正在使用 PyODBC 来备份我的数据库,使用以下代码:
SQL_command = """
BACKUP DATABASE [MyDatabase]
TO DISK = N'D:\MSSQL\BACKUP\MyDatabase_20141212.bak' WITH
NOFORMAT
, NOINIT
, NAME = N'MyDatabase_20141212'
, SKIP
, REWIND
, NOUNLOAD
, STATS = 10
"""
conn.cursor.execute(SQL_command)
conn.cursor.commit()
上面的代码给我一个错误消息:
pyodbc.编程错误:
('42000', '[42000] [Microsoft][ODBC SQL 服务器驱动程序][SQL Server]无法执行备份或还原操作 在一笔交易内。 (3021) (SQLExecDirectW);
[42000] [Microsoft][ODBC SQL Server 驱动程序][SQL Server]备份数据库是 异常终止。 (3013)')
我尝试在 SQL Server 中运行 SQL 代码,效果很好。
我可以知道我的代码有什么问题吗?
非常感谢。
您的错误说明
无法在事务内执行备份或恢复操作。
pyodbc 中默认启动事务,那么如何在不创建事务的情况下执行查询呢?只需打开自动提交即可:
conn.autocommit = true
// do stuff
conn.autocommit = false
pyodbc 常见问题解答有有关此的条目。
默认情况下,所有 pyodbc 连接都以事务开始。
您需要打开自动提交 - 在连接函数中使用 autocommit 关键字:
conn.autocommit = true
其他答案都是正确的。您确实需要设置自动提交。但是,事务将完成,但实际上不会进行备份,因为 SQL Server 中的一个怪癖以及它返回备份和恢复操作的状态消息的方式。
要解决此问题,您需要循环这些返回消息,直到没有剩余:
SQL_command = """
BACKUP DATABASE [MyDatabase]
TO DISK = N'D:\MSSQL\BACKUP\MyDatabase_20141212.bak' WITH
NOFORMAT
, NOINIT
, NAME = N'MyDatabase_20141212'
, SKIP
, REWIND
, NOUNLOAD
, STATS = 10
"""
conn.cursor.execute(SQL_command)
while conn.cursor.nextset():
pass
conn.cursor.close()
对我来说,它工作得很好,像这样:
while True:
time.sleep(1)
result = cursor.execute(
"""SELECT command FROM sys.dm_exec_requests
WHERE command LIKE 'BACKUP%'").fetchone()
if not result:
break