如何在不使用事务的情况下在 pymssql 中执行跨服务器存储过程?
How can I execute a cross-server Stored Procedure in pymssql without using Transactions?
我正在尝试将数据(使用存储过程)从一台服务器插入到另一台服务器。这是服务器架构的限制,我不得不解决它。
也就是说,我在 serverA
上有一个存储过程可以正常连接到 serverB
并且可以正常执行操作,因为两个服务器是链接的。
问题是 pymssql
使用事务,所以我不断收到此错误:
File "pymssql.pyx", line 465, in pymssql.Cursor.execute (pymssql.c:7190)
pymssql.OperationalError:
(7391, b'The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "ServerB" was unable to begin a distributed transaction. DB-Lib error message 20018, severity 16: General SQL Server error: Check messages from the SQL Server.)
当我在服务器上使用 BEGIN TRAN
作为存储过程的开头时,我看到了同样的错误,所以我得出结论,因为 pymssql
使用事务,我可能无法执行跨服务器分布式事务。
代码如下:
def databasedata(start, end):
startday = datetime.datetime.strptime(str(start), '%m/%d/%Y')
endday = datetime.datetime.strptime(str(end), '%m/%d/%Y')
conn = pymssql.connect( user=os.getenv('SQLUSER'),
password=os.getenv('SQLP'),
server='serverA',
database=os.getenv('SQLDB'))
cursor = conn.cursor()
cursor.execute(' select day from dbo.valid_days '
'where day between %s and %s',
(startday, endday)
)
days = cursor.fetchall()
for day in days:
date = ('%s-%s-%s' % day[0].timetuple()[:3])
cursor.execute('exec [hooper].[dbo].[cross_server_generation] %s', date)
conn.commit()
if __name__ == '__main__':
(firstday, secondday) = (sys.argv[1], sys.argv[2])
databasedata(firstday, secondday)
我没有使用 pymssql,而是选择 运行 通过 subprocess
将其作为子例程。
import subprocess
def databasedata(start, end):
startday = datetime.datetime.strptime(str(start), '%m/%d/%Y')
endday = datetime.datetime.strptime(str(end), '%m/%d/%Y')
conn = pymssql.connect( user=os.getenv('SQLUSER'),
password=os.getenv('SQLP'),
server='serverA',
database=os.getenv('SQLDB'))
cursor = conn.cursor()
cursor.execute(' select day from dbo.valid_days '
'where day between %s and %s',
(startday, endday)
)
days = cursor.fetchall()
cursor.close()
for day in days:
date = ('%s-%s-%s' % day[0].timetuple()[:3])
statement = 'exec [hooper].[dbo].[cross_server_generation] \'%s\'' % date
subprocess.call(["sqlcmd", "-S", sqlserver, "-Q", statement])
if __name__ == '__main__':
(firstday, secondday) = (sys.argv[1], sys.argv[2])
databasedata(firstday, secondday)
我正在尝试将数据(使用存储过程)从一台服务器插入到另一台服务器。这是服务器架构的限制,我不得不解决它。
也就是说,我在 serverA
上有一个存储过程可以正常连接到 serverB
并且可以正常执行操作,因为两个服务器是链接的。
问题是 pymssql
使用事务,所以我不断收到此错误:
File "pymssql.pyx", line 465, in pymssql.Cursor.execute (pymssql.c:7190)
pymssql.OperationalError:
(7391, b'The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "ServerB" was unable to begin a distributed transaction. DB-Lib error message 20018, severity 16: General SQL Server error: Check messages from the SQL Server.)
当我在服务器上使用 BEGIN TRAN
作为存储过程的开头时,我看到了同样的错误,所以我得出结论,因为 pymssql
使用事务,我可能无法执行跨服务器分布式事务。
代码如下:
def databasedata(start, end):
startday = datetime.datetime.strptime(str(start), '%m/%d/%Y')
endday = datetime.datetime.strptime(str(end), '%m/%d/%Y')
conn = pymssql.connect( user=os.getenv('SQLUSER'),
password=os.getenv('SQLP'),
server='serverA',
database=os.getenv('SQLDB'))
cursor = conn.cursor()
cursor.execute(' select day from dbo.valid_days '
'where day between %s and %s',
(startday, endday)
)
days = cursor.fetchall()
for day in days:
date = ('%s-%s-%s' % day[0].timetuple()[:3])
cursor.execute('exec [hooper].[dbo].[cross_server_generation] %s', date)
conn.commit()
if __name__ == '__main__':
(firstday, secondday) = (sys.argv[1], sys.argv[2])
databasedata(firstday, secondday)
我没有使用 pymssql,而是选择 运行 通过 subprocess
将其作为子例程。
import subprocess
def databasedata(start, end):
startday = datetime.datetime.strptime(str(start), '%m/%d/%Y')
endday = datetime.datetime.strptime(str(end), '%m/%d/%Y')
conn = pymssql.connect( user=os.getenv('SQLUSER'),
password=os.getenv('SQLP'),
server='serverA',
database=os.getenv('SQLDB'))
cursor = conn.cursor()
cursor.execute(' select day from dbo.valid_days '
'where day between %s and %s',
(startday, endday)
)
days = cursor.fetchall()
cursor.close()
for day in days:
date = ('%s-%s-%s' % day[0].timetuple()[:3])
statement = 'exec [hooper].[dbo].[cross_server_generation] \'%s\'' % date
subprocess.call(["sqlcmd", "-S", sqlserver, "-Q", statement])
if __name__ == '__main__':
(firstday, secondday) = (sys.argv[1], sys.argv[2])
databasedata(firstday, secondday)