0

0

pyodbc 读取 MS Access 时间类型数据的行为解析与处理

碧海醫心

碧海醫心

发布时间:2025-07-23 13:22:16

|

979人浏览过

|

来源于php中文网

原创

pyodbc 读取 MS Access 时间类型数据的行为解析与处理

本文深入探讨了使用 pyodbc 模块从 Microsoft Access 数据库查询 TIME 类型字段时,数据被解析为 datetime.datetime 对象的现象。由于 Access 内部将 TIME 视为带有默认日期 1899-12-30 的 DateTime 类型,pyodbc 会如实返回完整日期时间对象。教程将指导读者如何正确理解这一行为,并提供从返回的 datetime 对象中有效提取所需时间部分的实用方法,确保数据处理的准确性。

理解 MS Access 的时间数据类型

在使用 pyodbc 连接 microsoft access 数据库并查询时间(time)类型字段时,开发者可能会发现返回的数据格式并非预期的 hh:mm:ss 字符串,而是 datetime.datetime 对象,且日期部分固定为 1899-12-30。这并非 pyodbc 的错误,而是 access 数据库内部处理时间类型数据的方式所致。

Access 数据库并没有一个独立的 TIME 数据类型。所有日期和时间信息都存储在 DateTime 类型中。当用户在 Access 中创建一个只包含时间信息的字段(例如在设计视图中选择“日期/时间”类型,并设置格式为“时间”),Access 实际上是在内部将其存储为一个完整的 DateTime 值,其中日期部分被默认设置为 1899年12月30日。这个日期是 Access 用于表示“零日期”或仅时间值的基准日期。

因此,当 pyodbc 查询这类字段时,它忠实地返回了数据库中存储的完整 datetime.datetime 对象,包括了那个默认的基准日期。

示例场景与数据表现

假设我们有一个名为 Insersion 的表,其中包含一个 time_inserted 字段,其 DDL 定义如下:

CREATE TABLE Insersion (
    insersionID COUNTER PRIMARY KEY, 
    date_inserted DATE, 
    time_inserted TIME, 
    floaterID INT, 
    wholeID INT, 
    FOREIGN KEY (floaterID) REFERENCES [Float] (floaterID), 
    FOREIGN KEY (wholeID) REFERENCES [whole] (wholeID), 
    conversionType VARCHAR(30)
)

当使用 pyodbc 执行以下查询时:

SELECT [F].float, [I].time_inserted
FROM [Float] AS F, Insersion AS I
WHERE F.floaterID = I.floaterID;

Python 代码迭代结果会显示:

墨刀AIPPT
墨刀AIPPT

排版/配图/美化一键优化,3分钟产出专业级PPT

下载
# 预期:12:14:29
# 实际:datetime.datetime(1899, 12, 30, 12, 14, 29)

# 预期:12:16:39
# 实际:datetime.datetime(1899, 12, 30, 12, 16, 39)

可以看到,time_inserted 字段被解析为 datetime.datetime 对象,其日期部分始终是 1899-12-30。

提取所需时间信息

既然我们知道 pyodbc 返回的是一个标准的 datetime.datetime 对象,我们可以利用 Python datetime 模块提供的功能来提取所需的时间部分。最常用的方法有两种:使用 strftime() 方法进行格式化,或直接访问 hour, minute, second 等属性。

1. 使用 strftime() 进行格式化

strftime() 方法允许我们将 datetime 对象格式化为任意字符串形式。对于时间,常用的格式代码有:

  • %H: 24小时制的小时(00-23)
  • %M: 分钟(00-59)
  • %S: 秒(00-59)
import pyodbc
import datetime

# 假设 conn 是已建立的 pyodbc 数据库连接
# conn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=your_database.accdb;')

cursor = conn.cursor()
query = """
SELECT [F].float, [I].time_inserted
FROM [Float] AS F, Insersion AS I
WHERE F.floaterID = I.floaterID;
"""
cursor.execute(query)

print("--- 使用 strftime() 格式化时间 ---")
for row in cursor.fetchall():
    # row[1] 对应 time_inserted 字段
    time_obj = row[1] 
    if isinstance(time_obj, datetime.datetime):
        formatted_time = time_obj.strftime('%H:%M:%S')
        print(f"原始对象: {time_obj}, 格式化时间: {formatted_time}")
    else:
        print(f"非 datetime 对象: {time_obj}")

cursor.close()
# conn.close()

2. 直接访问属性

如果只需要小时、分钟、秒的数值,可以直接访问 datetime 对象的 hour, minute, second 属性。

import pyodbc
import datetime

# 假设 conn 是已建立的 pyodbc 数据库连接

cursor = conn.cursor()
query = """
SELECT [F].float, [I].time_inserted
FROM [Float] AS F, Insersion AS I
WHERE F.floaterID = I.floaterID;
"""
cursor.execute(query)

print("\n--- 直接访问时间属性 ---")
for row in cursor.fetchall():
    time_obj = row[1]
    if isinstance(time_obj, datetime.datetime):
        hour = time_obj.hour
        minute = time_obj.minute
        second = time_obj.second
        # 可以用 f-string 格式化输出,确保两位数显示
        print(f"原始对象: {time_obj}, 小时: {hour:02}, 分钟: {minute:02}, 秒: {second:02}")
        print(f"组合时间: {hour:02}:{minute:02}:{second:02}")
    else:
        print(f"非 datetime 对象: {time_obj}")

cursor.close()
# conn.close()

注意事项

  • 理解数据库底层机制: 这种 1899-12-30 日期前缀的行为是 Access 数据库的固有特性,并非 pyodbc 的问题。理解这一点有助于避免混淆和错误归因。
  • 一致性处理: 在处理从 Access 获取的时间数据时,始终预期并处理 datetime.datetime 对象,然后根据需求提取时间部分。这能确保代码的健壮性。
  • 性能考量: 对于大量数据,strftime() 方法通常效率较高,因为它直接将对象格式化为字符串。直接访问属性再手动拼接字符串也有效,但可能在极端情况下有细微性能差异。
  • 其他数据库: 这种行为仅限于 Access。其他数据库系统(如 SQL Server, MySQL, PostgreSQL)通常有独立的 TIME 类型,pyodbc 或其他 ORM 会将其映射为 Python 的 datetime.time 对象,而不是 datetime.datetime。

总结

当使用 pyodbc 从 Microsoft Access 数据库中读取 TIME 类型字段时,返回 datetime.datetime 对象并带有 1899年12月30日 的默认日期是符合预期的行为。这是因为 Access 内部将所有日期和时间信息统一存储为 DateTime 类型。开发者可以通过 datetime 对象的 strftime() 方法或直接访问其时间属性(hour, minute, second)来精确地提取所需的时间信息,从而正确处理和利用这些数据。理解这一底层机制对于在 Python 中有效操作 Access 数据库至关重要。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

1110

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

340

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

380

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2048

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

379

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

1602

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

585

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

439

2024.04.29

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

1

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
MySQL 教程
MySQL 教程

共48课时 | 2.5万人学习

MySQL 初学入门(mosh老师)
MySQL 初学入门(mosh老师)

共3课时 | 0.3万人学习

简单聊聊mysql8与网络通信
简单聊聊mysql8与网络通信

共1课时 | 844人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号