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的主要内容,如果未能解决你的问题,请参考以下文章

python中啥是变量变量命的命名,应遵循哪些规则

VC 读取SQLite数据库中的表的数据,该怎么解决

android sqlite禁止重复插入数据

Python Pandas 合并(和连接)是不是无法通过后缀参数重命名列?

如何调用sqlite数据库中的数据

SQLite插入 - 如何使用参数化值避免语法错误时插入任何文本