表示具有要加载到数据库中的日期时间对象的行的字典列表



我在一个文本文件中有以下几行,我使用python从数据库表中转储了这些行。

[{‘id’:1,‘name’:‘abcd’,‘date’:datetime.datetime(2021,3,13,18,54,40,314716(,‘comments’:无,‘status’:‘Success’},{‘id':2,‘name‘:‘efgh’,‘date':datetime.datetime

我希望将文件作为列表读取,并迭代表示每一行的字典,然后加载数据库表。

在python中,从文件中以列表的形式加载这些数据可以使用ast.literal_eval,但只有在文件内的列表中没有日期时间对象的情况下才能使用。

with open('file.txt') as f:
data = ast.literal_eval(f.read())

然而,当存在日期时间对象时,我会得到以下错误:

ValueError: malformed node or string: <_ast.Call object at 0x000001C1A755D240>

有没有任何方法可以将文件中的数据读取为python中的字典列表,这样它甚至可以与datetime对象一起工作,从而可以将数据加载到数据库表中?

将行从文件加载到数据库表中的任何其他方法也会有所帮助。我使用的数据库是Postgres。

您可以在整个字符串中删除datetime.datetime部分,留下一个元组,然后运行ast.literal_eval()并将每个元组转换为datetime.datetime()对象。

import ast
import datetime
with open('file.txt') as f:
data = ast.literal_eval(f.read().replace('datetime.datetime',''))
data
# [
#     {
#          'id': 1, 'name': 'abcd', 'date': (2021, 3, 13, 18, 54, 40, 314716),
#          'comments': None, 'status': 'Success'
#     }, 
#     {
#         'id': 2, 'name': 'efgh', 'date': (2021, 3, 14, 10, 4, 49, 9217),
#         'comments': None, 'status': 'Success'
#     }
# ]
data_w_datetime = [
{k: datetime.datetime(*v) if k == 'date' else v for k, v in d.items()}
for d in data
]
data_w_datetime
# [
#     {
#          'id': 1, 'name': 'abcd',
#          'date': datetime.datetime(2021, 3, 13, 18, 54, 40, 314716),
#          'comments': None, 'status': 'Success'
#     }, 
#     {
#         'id': 2, 'name': 'efgh',
#         'date': datetime.datetime(2021, 3, 14, 10, 4, 49, 9217),
#         'comments': None, 'status': 'Success'
#     }
# ]

然后,您可以使用psycopg2将数据加载到Postgres中,而无需使用execute_values进行迭代。

import psycopg2
from psycopg2.extras import execute_values
columns = data_w_datetime[0].keys()
query = "INSERT INTO mytable ({}) VALUES %s".format(','.join(columns))
# extract values from each dictionary and put them in a list of lists
values = [[value for value in d.values()] for d in data_w_datetime]
conn = psycopg2.connect(**db_params) # specify your own connection params
cursor = conn.cursor()
execute_values(cursor, query, values)
conn.commit()
cur.close()

最新更新