python sqlite插入命名参数或null

时间:2013-06-18 13:05:52

标签: python sqlite named-parameters

我正在尝试使用命名参数将字典中的数据插入数据库。我使用了一个简单的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:你没有提供绑定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文本文件构建它。

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

2 个答案:

答案 0 :(得分:13)

使用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)

答案 1 :(得分:1)

这个问题有一个更简单的解决方案,在大多数情况下应该是可行的; 只需转到 for (var i = 0; i < images.length; i++) { console.log(images[i].doc_type); if(!sortedImages[ images[i].doc_type ]){ sortedImages[images[i].doc_type] = []; } sortedImages[images[i].doc_type].push(images[i]); } executemany 列表,而不是 defaultdict列表。

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

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

executemany

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

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()