Python 使用pyodbc时,SQL Server DateTimeOffset将tz感知日期时间的偏移量更改为系统偏移量

Python 使用pyodbc时,SQL Server DateTimeOffset将tz感知日期时间的偏移量更改为系统偏移量,python,sql-server,pyodbc,datetimeoffset,Python,Sql Server,Pyodbc,Datetimeoffset,从python向SQL server数据类型datetimeoffset上载时区感知的datetime时出现问题 无论哪个时区上载到SQL Server,它总是在系统时间偏移量中显示偏移量。仅更改偏移量并不是转换实际日期时间 datetime = datetime.datetime.now(tz=pytz.timezone('UTC')) timeString = datetime.strftime("%Y-%m-%d %H:%M:%S%z") timeData = {'

从python向SQL server数据类型datetimeoffset上载时区感知的datetime时出现问题

无论哪个时区上载到SQL Server,它总是在系统时间偏移量中显示偏移量。仅更改偏移量并不是转换实际日期时间

    datetime = datetime.datetime.now(tz=pytz.timezone('UTC'))
    timeString = datetime.strftime("%Y-%m-%d %H:%M:%S%z")
    timeData = {'datetimeOFFSET':datetime, 'datetime':datetime, 'datetimeString':timeString}
    df = pd.DataFrame(data=timeData, index = np.array([1]))
python中的数据帧:

datetimeOFFSET                         datetime                           datetimeString
2019-12-30 10:29:07.913715+00:00       2019-12-30 10:29:07.913715+00:00   2019-12-30 10:29:07+0000
sql server中的结果:


我想要的是datetimeOFFSET列显示右偏移量+00:00,而不是系统偏移量+01:00。

是否尝试了此选项

Time zone offset aware and preservation     No
Daylight saving aware                       No
更新,2021年4月:

这仍然是一个与熊猫有关的问题

原始答案警告:包括1.4版中不推荐的过时SQLAlchemy 1.3使用模式

今天早上,SQLAlchemy中的datetimeoffset处理有了一些非常新的改进。它们将包含在下一个版本(可能是1.3.13)中,但在此期间,请尝试从最新的源代码安装1.3.x分支

pip安装-升级git+https://github.com/sqlalchemy/sqlalchemy@关系1\u 3 。。。看看这对你是否更有效

编辑:

经进一步调查,问题似乎在于to_sql。如果数据帧包含一行,则时区偏移丢失:

导入日期时间 从pprint导入pprint 将sqlalchemy作为sa导入 ... engine=sa.create\u engineconnection\u uri,fast\u executemany=True 测试环境 表名称='DateTimeOffset\u测试' engine.executesa.textfDROP表(如果存在)[{TABLE_name}] engine.executesa.textfCREATE TABLE[{TABLE_name}]id int主键,dto datetimeoffset 测试数据 my_tz=datetime.timezonedatetime.timedeltahours=-7 dto_值=datetime.datetime2020,1,1,0,0,0,tzinfo=my_tz 打印到值2020-01-01 00:00:00-07:00 ^ 行数=1 行数据=[x,rangenum\u行中x的dto\u值] df=pd.DataFramerow_数据,列=['id','dto'] printdf id dto 0 0 2020-01-01 00:00:00-07:00 ^ df.to_sqltable_名称,引擎,如果_exists='append',index=False result=engine.executesa.textfSELECT id,CASTdto作为varchar50作为来自[{table_name}]的foo.fetchall pprintresult [0, '2020-01-01 00:00:00.0000000 +00:00'] ^-错 但是,如果数据帧包含多行,则会正确上载datetimeoffset值:

... 行数=2 行数据=[x,rangenum\u行中x的dto\u值] df=pd.DataFramerow_数据,列=['id','dto'] printdf id dto 0 0 2020-01-01 00:00:00-07:00 1 1 2020-01-01 00:00:00-07:00 ^ df.to_sqltable_名称,引擎,如果_exists='append',index=False result=engine.executesa.textfSELECT id,CASTdto作为varchar50作为来自[{table_name}]的foo.fetchall pprintresult [0, '2020-01-01 00:00:00.0000000 -07:00', 1, '2020-01-01 00:00:00.0000000 -07:00'] ^-正确
如果你真的对此有强烈的感觉,你可能想对此提出质疑。

例如,使用df.to_sql会给我同样的错误,但方式不同。它不显示系统时间偏移量,而是显示UTC偏移量+00:00,与数据的实际偏移量无关。df.to_sqlDateTimeOffset_Test,如果_exists='append',con=engine,index=False->我很欣赏解释得很好的答案。但不幸的是,这并不能解决我的问题:。这可能是由于我的SQL Server上的问题造成的。是否可以运行SQL Profiler来查看发送到服务器的内容?当我运行它时,我看到exec sp_prepare@p1 output,N'@p1 int,@P2 datetimeoffset',N'插入[datetimeoffset_Test]id,dto值@p1,@P2',1,然后是exec sp_execute 2,0,'2020-01-01 00:00-07:00'和exec sp_execute 2,1,'2020-01-01 00:00-07:00'你说得对!它被错误地发送到服务器,但我不明白为什么:exec sp_description_undeclared_parameters N'插入[DateTimeOffset_Test][DateTimeOffset],datetime,[datetimeString]value@P1,@P2,@P3',然后是exec sp_execute 2,'2020-01-06 10:16:31:00','2020-01-06 10:16:31.2310000',N'2020-01-06 10:16:31+0000'。正如您所看到的,当datetime作为字符串第三列发送时,它是正确发送的,但当它是tz-aware datetime-first column.btw时则不正确。添加的+01:00是我的本地时间偏移