我想用字典把值插入到表中,我该怎么做?
import sqlite3
db = sqlite3.connect('local.db')
cur = db.cursor()
cur.execute('DROP TABLE IF EXISTS Media')
cur.execute('''CREATE TABLE IF NOT EXISTS Media(
id INTEGER PRIMARY KEY, title TEXT,
type TEXT, genre TEXT,
onchapter INTEGER, chapters INTEGER,
status TEXT
)''')
values = {'title':'jack', 'type':None, 'genre':'Action', 'onchapter':None,'chapters':6,'status':'Ongoing'}
#What would I Replace x with to allow a
#dictionary to connect to the values?
cur.execute('INSERT INTO Media VALUES (NULL, x)'), values)
cur.execute('SELECT * FROM Media')
meida = cur.fetchone()
print meida
有一个使用字典的解决方案。首先,sql语句
不会起作用,因为它假设您按照abarnert声明的
CREATE TABLE
语句中定义的顺序引用所有列。(见SQLite INSERT。)通过指定列修复后,可以使用命名占位符插入数据。这样做的好处是可以安全地转义关键字符,所以您不必担心。从Python sqlite-documentation:
如果试图使用
dict
同时指定列名和值,则不能这样做,至少不能直接这样做。这是SQL的固有特性。如果不指定列名列表,则必须按
CREATE TABLE
顺序指定列名,而不能按dict
顺序指定,因为dict
没有顺序。当然,如果您真的想,可以使用collections.OrderedDict
,确保它的顺序正确,然后传递values.values()
。但在这一点上,为什么不首先有一个list
(或者tuple
)?如果您绝对确定您已经按照正确的顺序获得了所有的值,并且希望按顺序而不是按名称引用它们,那么您所拥有的是一个list
,而不是一个dict
。在SQL中没有办法绑定列名(或表名等),只有值。
当然,您可以动态生成SQL语句。例如:
然而,这几乎总是一个坏主意。这实际上并不比生成和
exec
使用动态Python代码要好多少。而且您刚刚失去了使用占位符的所有好处,首先主要是防止SQL注入攻击,但也失去了在DB引擎中更快的编译、更好的缓存等不太重要的东西。最好是退后一步,从更高的层次来看待这个问题。例如,也许您并不真正想要一个静态的属性列表,而是一个名称值
MediaProperties
表?或者,或者,您可能需要某种基于文档的存储(无论是高性能的nosql系统,还是存储在shelve
中的一堆JSON或YAML对象)?使用named placeholders的替代方法:
您可以使用named parameters:
这仍然取决于
INSERT
语句中的列顺序(那些:
只用作values
dict中的键),但它至少不必在python端对值进行排序,另外,在values
中还可以有其他东西在这里被忽略;如果要将dict中的内容分开存储在多个表中,这可能是有用的。如果仍要避免重复这些名称,可以在执行伪查询后从
sqlite3.Row
结果对象或cur.description
中提取它们;在执行CREATE TABLE
的任何位置附近以python形式保存它们可能更明智。相关问题 更多 >
编程相关推荐