18

我正在尝试使用命名参数将字典中的数据插入数据库。我有一个简单的 SQL 语句,例如

SQL = "INSERT INTO status (location, arrival, departure) VALUES (:location, :arrival,:departure)"
dict = {'location': 'somewhere', 'arrival': '1000', 'departure': '1001'}
c.execute(SQL,dict)

将某处插入位置,1000 插入到达列,1001 插入离开列。

我实际拥有的数据将包含位置,但可能包含到达或出发,但可能不包含两者(在这种情况下,表中没有任何内容或 NULL 可以进入)。在这种情况下,我得到 sqlite3.ProgrammingError: You did not provide a value for binding 2。

我可以通过使用 defaultdict 来解决这个问题:

c.execute(SQL,defaultdict(str,dict))

为了让事情稍微复杂一点,我实际上将有一个字典列表,其中包含多个到达或离开的位置。

    ({'location': 'place1', 'departure': '1000'},
    {'location': 'palce2', 'arrival': '1010'},
    {'location': 'place2', 'departure': '1001'})

我希望能够用 c.executemany 运行它,但是我现在不能使用 defaultdict。

我可以遍历列表中的每个字典并运行许多 c.execute 语句,但 executemany 似乎是一种更简洁的方法。

为方便起见,我简化了这个示例,实际数据在字典中有更多条目,并且我从 JSON 文本文件构建它。

有人对我如何做到这一点有任何建议吗?

4

2 回答 2

18

用于None插入NULL

dict = {'location': 'somewhere', 'arrival': '1000', 'departure': None}

您可以使用默认字典和生成器来使用它executemany()

defaults = {'location': '', 'arrival': None, 'departure': None}

c.executemany(SQL, ({k: d.get(k, defaults[k]) for k in defaults} for d in your_list_of_dictionaries)
于 2013-06-18T13:12:33.857 回答
1

这个问题有一个更简单的解决方案,在大多数情况下应该是可行的;只需传递给 executemany 列表 defaultdict 而不是列表 dict

换句话说,如果您从头开始构建行,defaultdict则可以将行列表defaultdict直接传递给 command executemany,而不是将它们构建为字典,然后在使用之前修补情况executemany

以下工作示例(Python 3.4.3)说明了这一点:

import sqlite3
from collections import defaultdict
# initialization
db = sqlite3.connect(':memory:')
c = db.cursor()
c.execute("CREATE TABLE status(location TEXT, arrival TEXT, departure TEXT)")
SQL = "INSERT INTO status VALUES (:location, :arrival, :departure)"
# build each row as a defaultdict
f = lambda:None # use str if you prefer
row1 = defaultdict(f,{'location':'place1', 'departure':'1000'})
row2 = defaultdict(f,{'location':'place2', 'arrival':'1010'})
rows = (row1, row2)
# insert rows, executemany can be safely used without additional code
c.executemany(SQL, rows)
db.commit()
# print result
c.execute("SELECT * FROM status")
print(list(zip(*c.description))[0])
for r in c.fetchall():
    print(r)
db.close()

如果你运行它,它会打印:

('location', 'arrival', 'departure')
('place1', None, '1000') # None in Python maps to NULL in sqlite3
('place2', '1010', None)
于 2015-08-21T00:05:33.877 回答