【问题标题】:How can I export to sqlite (or another format) and retain the date datatype?如何导出到 sqlite(或其他格式)并保留日期数据类型?
【发布时间】:2019-08-11 10:16:25
【问题描述】:

我有一个脚本,可以将 CSV 加载到 pandas 数据框中,清理结果表(例如,删除无效值、将日期格式化为日期等)并将输出保存到本地 sqlite .db 文件。

然后我有其他脚本可以打开该数据库文件并对其执行其他操作。

我的问题是 Sqlite3 没有明确的日期格式:https://www.sqlite.org/datatype3.html 这意味着日期操作失败,例如:

df_read['Months since mydate 2'] = (  pd.to_datetime('15-03-2019') - df_read['mydate'] )

返回

TypeError: 不支持的操作数类型 -: 'Timestamp' 和 'str'

如何以跟踪所有数据类型(包括日期)的方式导出我的数据框?

我想到了以下几点:

  • 导出到另一种格式,但是什么格式?一个合适的 SQL Server 会很棒,但在这种情况下我无权访问任何一个。我需要一种明确声明每列数据类型的格式,因此 CSV 不是一个选项。

  • 在从 SQL lite 读取列之后,有一个小函数可以将列重新转换为日期。但这意味着我必须手动跟踪列日期 - 在大型数据集上会很麻烦且速度很慢。

  • 在 SQL lite 数据库中有另一个表,用于跟踪哪些列是日期,以及它们的格式(例如 %Y-%m-%d);这可以帮助重新转换为日期,但它仍然感觉非常麻烦、笨重且非常不符合 Python 风格。

这是我的意思的一个简单示例:

import numpy as np
import pandas as pd
import sqlite3
num=int(10e3)
df=pd.DataFrame()
df['month'] = np.random.randint(1,13,num)
df['year'] = np.random.randint(2000,2005,num)
df['mydate'] = pd.to_datetime(df['year'] * 10000 + df['month']* 100 + df['month'], format ='%Y%m%d' )
df.iloc[20:30,2]=np.nan

#this works
df['Months since mydate'] = (  pd.to_datetime('15-03-2019') - df['mydate'] )

conn=sqlite3.connect("test_sqllite_dates.db")
df.to_sql('mydates',conn, if_exists='replace')
conn.close()

conn2=sqlite3.connect("test_sqllite_dates.db")

df_read=pd.read_sql('select * from mydates',conn2 )
# this doesn't work
df_read['Months since mydate 2'] = (  pd.to_datetime('15-03-2019') - df_read['mydate'] )
conn2.close()

print(df.dtypes)
print(df_read.dtypes)

【问题讨论】:

    标签: python pandas sqlite datetime sqlalchemy


    【解决方案1】:

    如图here (w/ sqlite writing),here (reading back from sqlite),解决方法是在sqlite中创建列类型为日期时间,这样在读回时python会自动转换为datetime类型。

    请注意,当您连接到数据库时,您需要提供参数 detect_types=sqlite3.PARSE_DECLTYPES

    【讨论】:

    • 谢谢你——这行得通!但是,我必须说我还没有完全理解发生了什么。你能帮我澄清一下吗?文档说 SQL lite 没有日期时间格式。那么detect_types如何让pandas理解该列是一个日期呢?我什至将列名更改为“香蕉”,它仍然有效。 SQL lite 没有日期格式,但会存储一些元数据,帮助其他程序将该列解释为日期?
    • 对不起,我是 OTK。日期通常存储在ISO format,因此当您以这种标准格式存储它们时,您也可以检索它们,即使它不是日期类型的字段,而只是一个字符串。就像我写+45 2548655(随机号码),没有人说它是电话,但这是写电话号码的标准格式
    猜你喜欢
    • 2021-06-02
    • 1970-01-01
    • 2022-12-20
    • 2019-03-16
    • 2013-01-05
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多