You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将pandas的datetime64转换为Django可识别的DateField类型?

问题原因分析

为什么pandas写入后日期列是NUM类型

SQLite本身采用动态类型系统,没有原生的DATE/TIMESTAMP存储类型。pandas调用to_sql方法写入SQLite时,默认会将datetime64类型的字段转换为Unix时间戳(数值格式)存储,因此你查询表结构时会看到该字段类型标记为NUM。

为什么Django inspectdb识别为TextField

inspectdb是通过读取数据库的表结构元数据反向生成模型,SQLite的NUM类型没有明确的类型标识对应Django的日期字段,因此自动推断为兼容性最高的TextField。

修复方案

场景1:数据还未写入数据库,从写入环节修正

  1. 提前导入sqlalchemy的日期类型用于指定字段映射:
from sqlalchemy import create_engine, DateTime
import pandas as pd
  1. 构造类型映射字典,调用to_sql时指定dtype参数:
# 连接SQLite数据库
engine = create_engine('sqlite:///你的数据库文件路径.db')
# 指定字段类型映射
dtype_map = {
    'Start Date': DateTime()
}
# 写入数据
excel_table.to_sql(
    name=table_name,
    con=engine,
    index=False,
    dtype=dtype_map,
    if_exists='replace' # 按需修改写入模式,可选append/fail
)

写入后该字段会以ISO标准日期格式存储,inspectdb也可以直接识别为DateTimeField。

场景2:数据已写入数据库,无需重导直接修改模型

直接手动修改自动生成的模型字段类型即可,Django ORM会自动处理不同存储格式的日期转换:

# 仅存储日期用DateField,带时分秒用DateTimeField
start_date = models.DateField(db_column='Start Date', blank=True, null=True)

修改后即可正常使用ORM的日期过滤、排序功能,示例如下:

# 筛选2020-12-31之后的记录
TableName.objects.filter(start_date__gt='2020-12-31')
# 按日期升序排序
TableName.objects.order_by('start_date')

如果修改后出现日期解析异常,可以执行SQL将原数值型时间戳批量转换为标准日期格式:

注意SQLite对ALTER COLUMN的支持有限,因此采用新增列替换的方式修改存量字段格式更为稳妥

-- SQLite执行以下语句,注意替换表名
ALTER TABLE TableName ADD COLUMN temp_start_date TEXT;
UPDATE TableName SET temp_start_date = datetime("Start Date", 'unixepoch');
ALTER TABLE TableName DROP COLUMN "Start Date";
ALTER TABLE TableName RENAME COLUMN temp_start_date TO "Start Date";

内容的提问来源于stack exchange,提问作者PipEvangelist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 13:36:03