使用行工厂将字典插入 SQLite 的本机方法,如果可能的话,使用自动更新的列数



如如何从sqlite查询获取dict?中所述,row_factory查询SQLite数据库时获取dict很有帮助:

import sqlite3
conn = sqlite3.connect(":memory:")
conn.row_factory = sqlite3.Row
conn.execute('create table test (a text, b text, c int)')
conn.execute('insert into test values (?, ?, ?)', ('hello', 2, 17))
for r in conn.execute('select * from test'):
print(dict(r))
# {'a': 'hello', 'b': '2', 'c': 17}

查询的结果直接是一个dict,这有时非常有用。

问题:使用row_factory轻松地将dict直接INSERT到数据库中时,是否也可以?

这是部分解决方案:

d = {'a': 1, 'b': 2, 'c': 3}
conn.execute('insert into test ({}) values ({})'.format(','.join(d.keys()), ','.join(['?'] * len(d))), tuple(d.values()))

但它并不是真正的"蟒蛇"。

有没有一种更干净的方法将字典直接插入SQLite数据库,例如,通过使用row_factory

附带评论:它还可以"自动增长"表定义,即如果我插入d = {'newkey': 1, 'b': 2, 'c': 3},它会自动向表添加新列。

由于我在评论中提到的原因,如果不用您自己的写入数据库文件的方式替换 SQL 接口,可能无法"本机"执行此操作,但当然有可能使这段代码更"pythonic",正如你提到的:

def sqlify_list(string_iterable):
""" ('a', 'b', 'c') -> '(a, b, c)' """
return f'({",".join(string_iterable)})'
def insert_dict_into_table(conn, table_name, _dict):
conn.execute(
'insert into {table_name} {keys} values {replacement_fields}'.format(
table_name=table_name,
keys=sqlify_list(d), # dict.__iter__ yields the keys, so .keys() isn't necessary
replacement_fields=sqlify_list('?'*len(d)) # str.__iter__ yields characters, so ','.join('?'*5) is equivalent to ','.join(['?']*5)
),
d.values()
)
d = {'a': 1, 'b': 2, 'c': 3}
insert_dict_into_table(conn, 'test', d)

至于

它还可以"自动增长"表定义,那就太好

据我所知,关系数据库通常不用于这种临时模式更改。也许将字典作为 JSON 存储在数据库中会更简单?或者切换到像MongoDB这样的无模式数据库?

最新更新