当使用pyodb时,SQL Server DateTimeOffset将具有tz意识的datetime的偏移量更改为系统偏移量

2024-09-29 06:24:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我在从python向sqlserver数据类型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中的结果:

enter image description here

我想要的是datetimeOFFSET列显示右偏移(+00:00),而不是系统偏移(+01:00)。你知道吗


Tags: sqldatetimeserver系统时间nowtz偏移量
2条回答

你试过这个选项吗?你知道吗

Time zone offset aware and preservation     No
Daylight saving aware                       No

SQLAlchemy中的datetimeoffset处理最近有了一些改进(如“今早”)。它们将包含在下一个版本(可能是1.3.13)中,但在此期间,请尝试从1.3.x分支的最新源安装。。。你知道吗

pip install  upgrade git+https://github.com/sqlalchemy/sqlalchemy@rel_1_3

。。。看看这对你是否更有效。你知道吗

编辑:

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

import datetime
from pprint import pprint

import sqlalchemy as sa

# ...

engine = sa.create_engine(connection_uri, fast_executemany=True)

# test environment
table_name = 'DateTimeOffset_Test'
engine.execute(sa.text(f"DROP TABLE IF EXISTS [{table_name}]"))
engine.execute(sa.text(f"CREATE TABLE [{table_name}] (id int primary key, dto datetimeoffset)"))

# test data
my_tz = datetime.timezone(datetime.timedelta(hours=-7))
dto_value = datetime.datetime(2020, 1, 1, 0, 0, 0, tzinfo=my_tz)
print(dto_value)  # 2020-01-01 00:00:00-07:00
#                                        ^

num_rows = 1
row_data = [(x, dto_value) for x in range(num_rows)]
df = pd.DataFrame(row_data, columns=['id', 'dto'])
print(df)
#    id                       dto
# 0   0 2020-01-01 00:00:00-07:00
#                            ^
df.to_sql(table_name, engine, if_exists='append', index=False)
result = engine.execute(sa.text(f"SELECT id, CAST(dto as varchar(50)) AS foo FROM [{table_name}]")).fetchall()
pprint(result)
# [(0, '2020-01-01 00:00:00.0000000 +00:00')]
#                                     ^   wrong

但是,如果DataFrame包含多行,则会正确上载datetimeoffset值:

# ...

num_rows = 2
row_data = [(x, dto_value) for x in range(num_rows)]
df = pd.DataFrame(row_data, columns=['id', 'dto'])
print(df)
#    id                       dto
# 0   0 2020-01-01 00:00:00-07:00
# 1   1 2020-01-01 00:00:00-07:00
#                            ^
df.to_sql(table_name, engine, if_exists='append', index=False)
result = engine.execute(sa.text(f"SELECT id, CAST(dto as varchar(50)) AS foo FROM [{table_name}]")).fetchall()
pprint(result)
# [(0, '2020-01-01 00:00:00.0000000 -07:00'), 
#  (1, '2020-01-01 00:00:00.0000000 -07:00')]
#                                     ^   correct

如果你真的对此有强烈的感觉,你可能想对此提出一个pandas issue。你知道吗

相关问题 更多 >