python sqlite插入命名参数或null
Posted
技术标签:
【中文标题】python sqlite插入命名参数或null【英文标题】:python sqlite insert named parameters or null 【发布时间】:2013-06-14 17:06:22 【问题描述】:我正在尝试使用命名参数将字典中的数据插入数据库。我有一个简单的 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 文本文件构建它。
有人对我如何做到这一点有任何建议吗?
【问题讨论】:
【参考方案1】:使用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)
【讨论】:
谢谢马丁 - 这行得通。对于遇到此问题的任何其他人,默认字典需要包含每个可能项目的条目,即使实际字典将始终具有它。此外,executemany 行上缺少最后一个右括号。【参考方案2】:这个问题有一个更简单的解决方案,在大多数情况下应该是可行的; 只需传递给 executemany
列表 defaultdict
而不是 dict
列表。
换句话说,如果您从头开始将行构建为defaultdict
,您可以将defaultdict
行的列表直接传递给命令executemany
,而不是将它们构建为字典,然后在使用@ 之前修补情况987654327@.
以下工作示例 (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)
【讨论】:
以上是关于python sqlite插入命名参数或null的主要内容,如果未能解决你的问题,请参考以下文章