sqlite3 returns 日期时间的字节字符串
sqlite3 returns byte string for datetime
我有一个sqlite3数据库:
import sqlite3
import pandas as pd
from datetime import datetime
batch_size = 10
con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
table = """CREATE TABLE my_table(DateCreated DATETIME);"""
cur.execute(table)
DateCreated = [datetime(2020, 12, 1, 1, 1)] * batch_size
x = list(pd.DataFrame({'DateCreated':DateCreated}).to_records(index=False))
query = """INSERT INTO my_table (DateCreated) values (?);"""
cur.executemany(query, x)
当我想检索我的日期时间时,sqlite3 returns 字节字符串而不是日期时间对象:
cur.execute("SELECT * FROM my_table;")
cur.fetchone()
>> (b'\x00\xf8\xea\x08\xf4qL\x16',)
我做错了什么?我检查了 this issue 但它并不真正适用于我的问题。我还尝试将 sqlite 数据类型从 DATETIME 更改为 TIMESTAMP,但收到 ValueError: not enough values to unpack (expected 2, got 1)
。我正在使用 Python 3.8.10.
问题在于我使用了 pandas' .to_record()
方法。如果我删除该步骤并提供 元组 列表而不是 numpy 记录 列表,则数据库 returns 日期时间正确.
import sqlite3
import pandas as pd
from datetime import datetime
batch_size = 10
con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
table = """CREATE TABLE my_table(DateCreated DATETIME);"""
cur.execute(table)
DateCreated = [(datetime(2020, 12, 1, 1, 1),)] * batch_size
query = """INSERT INTO my_table (DateCreated) values (?);"""
cur.executemany(query, DateCreated)
cur.execute("SELECT * FROM my_table;")
cur.fetchall()
您的代码片段中有两个错误:sqlite3 列的正确数据类型是 timestamp
,而不是 datetime
。 Sqlite3 很奇特,它只接受任何内容并将所有内容在内部存储为字符串 - 它是 Python 驱动程序,它将以不同方式处理列类型“时间戳”,并且能够直接接受和检索日期时间对象。
也就是说,“df.to_record”调用也无济于事,因为它将 pandas 日期时间检索为字符串。正确的做法是检索每个 pandas 单元格值并对其调用 .to_pydatetime()
。
因此,如果您需要将示例中未给出的另一个数据框转换为 sqlite,则此类代码有效:
import sqlite3
import pandas as pd
from datetime import datetime
batch_size = 10
con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
table = """CREATE TABLE my_table(DateCreated timestamp)"""
cur.execute(table)
DateCreated = [datetime(2020, 12, 1, 1, 1)] * batch_size
x = [(rec.to_pydatetime(),) for rec in pd.DataFrame({'DateCreated':DateCreated})["DateCreated"]]
query = """INSERT INTO my_table (DateCreated) values (?)"""
cur.executemany(query, x)
我在上面编写 x =
表达式的方式将允许您从数据框中 select 所需的列,并仅在所需的字段中调用 .to_pydatetime()
。
如果您的数据框有 5 个其他列,并且日期时间在第 3 个 [index 2],这有效:
x = [(*rec[0:2], rec[2].to_pydatetime(), *rec[3:]) for _, rec in df.iterrows()]
而且,如果您根本不从 pandas 工作流程转换内容,则无需干预,只需将日期时间对象创建为元组并将其插入即可:
x = [(datetime.now(),) for i in range(10)]
我有一个sqlite3数据库:
import sqlite3
import pandas as pd
from datetime import datetime
batch_size = 10
con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
table = """CREATE TABLE my_table(DateCreated DATETIME);"""
cur.execute(table)
DateCreated = [datetime(2020, 12, 1, 1, 1)] * batch_size
x = list(pd.DataFrame({'DateCreated':DateCreated}).to_records(index=False))
query = """INSERT INTO my_table (DateCreated) values (?);"""
cur.executemany(query, x)
当我想检索我的日期时间时,sqlite3 returns 字节字符串而不是日期时间对象:
cur.execute("SELECT * FROM my_table;")
cur.fetchone()
>> (b'\x00\xf8\xea\x08\xf4qL\x16',)
我做错了什么?我检查了 this issue 但它并不真正适用于我的问题。我还尝试将 sqlite 数据类型从 DATETIME 更改为 TIMESTAMP,但收到 ValueError: not enough values to unpack (expected 2, got 1)
。我正在使用 Python 3.8.10.
问题在于我使用了 pandas' .to_record()
方法。如果我删除该步骤并提供 元组 列表而不是 numpy 记录 列表,则数据库 returns 日期时间正确.
import sqlite3
import pandas as pd
from datetime import datetime
batch_size = 10
con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
table = """CREATE TABLE my_table(DateCreated DATETIME);"""
cur.execute(table)
DateCreated = [(datetime(2020, 12, 1, 1, 1),)] * batch_size
query = """INSERT INTO my_table (DateCreated) values (?);"""
cur.executemany(query, DateCreated)
cur.execute("SELECT * FROM my_table;")
cur.fetchall()
您的代码片段中有两个错误:sqlite3 列的正确数据类型是 timestamp
,而不是 datetime
。 Sqlite3 很奇特,它只接受任何内容并将所有内容在内部存储为字符串 - 它是 Python 驱动程序,它将以不同方式处理列类型“时间戳”,并且能够直接接受和检索日期时间对象。
也就是说,“df.to_record”调用也无济于事,因为它将 pandas 日期时间检索为字符串。正确的做法是检索每个 pandas 单元格值并对其调用 .to_pydatetime()
。
因此,如果您需要将示例中未给出的另一个数据框转换为 sqlite,则此类代码有效:
import sqlite3
import pandas as pd
from datetime import datetime
batch_size = 10
con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
table = """CREATE TABLE my_table(DateCreated timestamp)"""
cur.execute(table)
DateCreated = [datetime(2020, 12, 1, 1, 1)] * batch_size
x = [(rec.to_pydatetime(),) for rec in pd.DataFrame({'DateCreated':DateCreated})["DateCreated"]]
query = """INSERT INTO my_table (DateCreated) values (?)"""
cur.executemany(query, x)
我在上面编写 x =
表达式的方式将允许您从数据框中 select 所需的列,并仅在所需的字段中调用 .to_pydatetime()
。
如果您的数据框有 5 个其他列,并且日期时间在第 3 个 [index 2],这有效:
x = [(*rec[0:2], rec[2].to_pydatetime(), *rec[3:]) for _, rec in df.iterrows()]
而且,如果您根本不从 pandas 工作流程转换内容,则无需干预,只需将日期时间对象创建为元组并将其插入即可:
x = [(datetime.now(),) for i in range(10)]