【发布时间】:2021-10-08 16:56:35
【问题描述】:
我的目标是从 pandas 数据框中获取数据并插入 SQL 数据库。但是,我在时间和 UTC 方面遇到了一些问题。我将其分解为 3 个场景,从下面的代码中只需取消注释为每个场景标记的相关代码行。
场景 1,在 pandas 中将日期转换为日期/时间(非 UTC),然后插入到 sql 中,我收到以下错误消息:
"发生异常:ValueError Tz-aware datetime.datetime 不能 转换为 datetime64 除非 utc=True 文件 “/home/tbgiot04/OEE_forge/OEE_module/test_sql.py”,第 34 行,在 df.to_sql("test_table", engn, if_exists='replace')"
utc=True 的场景 2 我收到以下错误,导致未插入数据。
发生异常:ProgrammingError (pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]一张表只能有一个时间戳列。因为表 'test_table' 已经有一个,不能添加列 'end_date'。 (2738)(SQLExecDirectW)“)[SQL:创建表test_table([索引] BIGINT NULL,employee_no BIGINT NULL,start_date TIMESTAMP NULL, end_date TIMESTAMP NULL )
](此错误的背景:http://sqlalche.me/e/13/f405)文件 “/home/tbgiot04/OEE_forge/OEE_module/test_sql.py”,第 37 行,在 df.to_sql("test_table", engn, if_exists='replace')
场景 3,我有 utc = True 行和 dt.tz_localize 行。 pandas/SQL alchemy 发送数据但时间不正确。 pandas DataFrame 和 SQL 数据显示相同,但与源代码中的代码不匹配。如何正确地将这些数据插入 SQL 数据库?
employee_no start_date end_date
0 1 2019-12-05 15:55:47 2019-12-05 15:55:47
1 2 2021-07-13 21:38:39 2021-07-13 21:38:39
.
import pandas as pd
from sqlalchemy import create_engine
AZUREUID = 'tb-test' # Azure SQL database userid
AZUREPWD = 'test' # Azure SQL database password
AZURESRV = 'tb-sql01.database.windows.net' # Azure SQL database server name (fully qualified)
AZUREDB = 'TB-test' # Azure SQL database name (if it does not exit, pandas will create it)
TABLE = 'DataTable' # Azure SQL database table name
#DRIVER = 'ODBC Driver 13 for SQL Server' # ODBC Driver
#DRIVER = 'SQL Server Native Client 11.0' # ODBC Driver
#DRIVER={/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.0.so.1.1}
connectionstring = 'mssql+pyodbc://{uid}:{password}@{server}:1433/{database}?driver={driver}'.format(
uid=AZUREUID,
password=AZUREPWD,
server=AZURESRV,
database=AZUREDB,
driver=DRIVER.replace(' ', '+'))
engn = create_engine(connectionstring)
d = {"employee_no" : [1,2], "start_date" : ["2019-12-05 15:55:47 +00:00","2021-07-13 22:38:39 +01:00"] , "end_date" : ["2019-12-05 15:55:47 +00:00","2021-07-13 22:38:39 +01:00"] }
df = pd.DataFrame(data=d)
df["start_date"] = pd.to_datetime(df["start_date"]) # senario 1
df["end_date"] = pd.to_datetime(df["end_date"]) # senario 1
#df["start_date"] = pd.to_datetime(df["start_date"], utc=True) # senario 2 and 3
#df["end_date"] = pd.to_datetime(df["end_date"], utc=True) # senario 2 and 3
# df["start_date"] = df["start_date"].dt.tz_localize(None) # senario 3
# df["end_date"] = df["end_date"].dt.tz_localize(None) # senario 3
print(df)
df.to_sql("test_table", engn, if_exists='replace')
【问题讨论】:
-
SQL Server(我怀疑还有 Azure SQL)接受 properly-formatted string literals 的
datetimeoffset列。虽然通常建议在这种情况下对日期/时间值使用“正确的”日期时间对象,但最好不尝试转换字符串,特别是因为它们看起来已经采用格式T-SQL 需要的。 -
非常感谢您的快速回答。如果我将它们保留为对象,它们将作为 varchar 导入。在 SQL 中使用日期时间功能的最佳方式是什么。我有很多带有日期的列,我只是拿出 2 个作为示例。
-
在 pandas 中是否可以将 utc 时间转换为 uk 时间?
标签: python sql-server sqlalchemy