【问题标题】:How to convert Pandas DataFrame column from Pandas datetime64[ns] to Pyodbc SQL_Timestamp如何将 Pandas DataFrame 列从 Pandas datetime64[ns] 转换为 Pyodbc SQL_Timestamp
【发布时间】:2017-12-04 23:42:51
【问题描述】:

我正在尝试通过 pyodbc 将 Pandas Dataframe 填充到 empty MS Access 2016 表中。当我尝试将 Dataframes 插入 Access 时收到以下错误消息:pyodbc.dataerror: ('22008', [ODBC Microsoft Access Driver]Datetime field overflow

研究表明 MS Access Date/Time 数据类型对应于 ODBC SQL_TIMESTAMP 数据类型。

我尝试了以下方法将 datetime64[ns] 转换为 SQL_TIMESTAMP:

import datetime
cursor.execute("INSERT sql statement...VALUES(?)", datetime.datetime(order_date))  

但是,我收到此错误:TypeError: an integer is required (got type Timestamp)。

我需要做什么才能成功地将 Pandas/Numpy 的 datetime64[ns] 值填充到 Access 表中?我是否需要将它们转换为 SQL_TIMESTAMP 以及如何转换?


编辑: 我尝试在下面运行 Gord Thompson 的解决方案,但遇到了这个错误:
import datetime

dt = dt64_to_datetime(dt_ns)

>> AttributeError:'datetime' has no attribute 'utcfromtimestamp'

这个错误背后的原因是什么? (在 pyodbc 4.0.17、Python 3.6.2、MS Access 2016 上测试)

【问题讨论】:

  • edit你的问题表明你从print(repr(order_date))print(order_date.dtype)得到什么。
  • 我使用了from datetime import datetime。如果您只是import datetime,那么您可能需要使用datetime.datetime.utcfromtimestamp
  • @ Gord Thompson - 我遵循了您的解决方案,但出现以下错误:OSError: [Errno 22] Invalid argument。我相信这是因为输入值是numpy.datetime64('NaT')。我可以对 NaT 值做些什么?

标签: python dataframe odbc pyodbc ms-access-2016


【解决方案1】:

我需要做什么才能成功地将 Pandas/Numpy 的 datetime64[ns] 值填充到 Access 表中?我是否需要将它们转换为 SQL_TIMESTAMP 以及如何转换?

this excellent answer 中所示,您可能需要将numpy.datetime64 值转换为Python 的datetime 值,可能像这样:

def dt64_to_datetime(dt64):
    if np.isnat(dt64):
        return None
    else:
        unix_epoch = np.datetime64(0, 's')
        one_second = np.timedelta64(1, 's')
        seconds_since_epoch = (dt64 - unix_epoch) / one_second
        return datetime.utcfromtimestamp(seconds_since_epoch)

示例用法:

dt_ns = np.datetime64('2017-10-24 05:34:20.123456').astype('datetime64[ns]')
print(repr(dt_ns))  # numpy.datetime64('2017-10-24T05:34:20.123456000')
print(f'dt_ns.dtype: {dt_ns.dtype}')  # dt_ns.dtype: datetime64[ns]
dt = dt64_to_datetime(dt_ns)
print(repr(dt))  # datetime.datetime(2017, 10, 24, 5, 34, 20, 123456)

sql = "UPDATE tablename SET datetimefield = ? WHERE id=1"
params = (dt,)
crsr.execute(sql, params)

(使用 pyodbc 4.0.21 和 Access 2010 测试。)

【讨论】:

  • @ Gord Thompson - 你知道 Pandas/Numpy datetime64 和 datetime64[ns] 值之间的区别吗?
  • @Mook - 我没有,但在这种情况下似乎也没有什么不同。我已经更新了我的答案。
  • @ Gord Thompson - 我对您的解决方案感到困惑。当我打印 datetime64[ns] 值时,它看起来像这样:2017-01-01。此外,我正在尝试使用 SQL INSERT 语句将 Order_date 列值插入 Access。
  • @Mook - 我也很困惑,因为np.datetime64('2017-01-01').astype('datetime64[ns]') 打印为numpy.datetime64('2017-01-01T00:00:00.000000000'),它也适用于更新(在转换为datetime 之后)。
  • @ Gord Thompson - 我更新了我的问题以试图消除一些混乱。我正在尝试将此 Pandas 列填充到一个空的 Access 表中。所以 SQL UPDATE 语句可能不起作用。
猜你喜欢
  • 2020-11-05
  • 2017-01-05
  • 2020-04-28
  • 2014-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多