Julia导入含Datetime类型的SQL数据到DataFrame遇格式错误
解决MySQL datetime列导入DataFrame时的格式错误
错误原因
从栈追踪可以看出,MySQL.jl驱动错误地将表中的datetime类型列(如DATA、OKRES_START)映射为DecFP.Dec64数值类型,导致解析2017-01-01 00:00:00这类日期字符串时抛出格式错误。
解决方案
方法1:查询时显式转换日期列,再解析为DateTime
修改SQL查询,将datetime列转为字符串,导入DataFrame后再用Julia的Dates包解析为DateTime类型:
# 导入必要包 using DataFrames, DBInterface, MySQL, Dates # 显式转换datetime列为字符串 query = """ SELECT id, CAST(DATA AS CHAR) AS DATA, ROK, MIESIAC, WYM, CAST(OKRES_START AS CHAR) AS OKRES_START, CAST(OKRES_STOP AS CHAR) AS OKRES_STOP, CAST(OKRES_KSIEGOWY AS CHAR) AS OKRES_KSIEGOWY, MIESIAC_NAZWA, MIESIAC_ROK, TYDZIEN_NR, DZIEN, DZIEN_TYG, DZIEN_TYG_NAZWA FROM calendar_dict; """ # 执行查询并转为DataFrame result = DBInterface.execute(connect, query) result_df = DataFrame(result) # 将字符串列解析为DateTime类型 datetime_cols = [:DATA, :OKRES_START, :OKRES_STOP, :OKRES_KSIEGOWY] for col in datetime_cols result_df[!, col] = DateTime.(result_df[!, col], "yyyy-mm-dd HH:MM:SS") end
方法2:修改MySQL.jl的类型映射规则
重写MySQL驱动的类型转换逻辑,让datetime类型直接映射为Julia的DateTime:
using DataFrames, DBInterface, MySQL, Dates # 重写cast方法,处理datetime类型转换 import MySQL: cast function cast(::Type{Union{Missing, DateTime}}, s::String) isempty(s) && return missing return DateTime(s, "yyyy-mm-dd HH:MM:SS") end # 执行原查询并转为DataFrame query = "select * from calendar_dict;" result = DBInterface.execute(connect, query) result_df = DataFrame(result)
也可以在创建数据库连接时直接指定类型映射:
# 创建连接时指定datetime类型对应Julia的DateTime connect = MySQL.connect( "your_host", "your_user", "your_password", "your_db"; type_map=Dict(MySQL.MYSQL_TYPE_DATETIME => DateTime, MySQL.MYSQL_TYPE_TIMESTAMP => DateTime) )
方法3:检查表结构定义
确认MySQL表中DATA、OKRES_START等列的类型确实是DATETIME或TIMESTAMP,而非被错误定义为数值类型(如DECIMAL)。若类型错误,需先修改表结构:
ALTER TABLE calendar_dict MODIFY COLUMN DATA DATETIME; ALTER TABLE calendar_dict MODIFY COLUMN OKRES_START DATETIME; -- 其他日期列同理
内容的提问来源于stack exchange,提问作者przybyl3k
相关产品推荐
相关产品推荐

