我已经为sqlite3 db表编写了以下初始化例程,但有些东西告诉我这是a)脆弱,和/或b)只是一个坏主意(tm)。
概念是如果表不存在或者尚未初始化,则try块将出错并且将创建数据。在初始测试中,这是有效的 - 虽然我没有看到脚本运行时打印到控制台的默认值:我打印出一个空元组。使用sqlite shell检查数据库我看到数据存在。
但是那种琐碎的感觉依旧存在,这种方法存在一些非常错误。思考?意见?建议?
import sqlite3 as lite
import sys
def insert_defaults():
conn = lite.connect('db.sqlite')
with conn:
cur = conn.cursor()
defaults = (
('mykey','value for key one'),
('anotherkey','value for key two')
)
cur.executemany("INSERT INTO Settings(key,value) VALUES ( ?, ? )", defaults)
def initialize():
conn = lite.connect('db.sqlite')
settings = ()
try:
conn.row_factory = lite.Row
cur = conn.cursor()
cur.execute("SELECT * FROM Settings")
if cur.rowcount < 1:
insert_defaults()
cur.execute("SELECT * FROM Settings")
settings = cur.fetchall()
except lite.Error, e:
print "Error: %s" % e.args[0]
print "Trying to create missing table"
try:
cur.execute( "DROP TABLE IF EXISTS Settings" )
cur.execute("CREATE TABLE IF NOT EXISTS Settings (id INTEGER PRIMARY KEY, key TEXT NOT NULL, value TEXT)")
insert_defaults()
except lite.Error, e:
if conn:
conn.rollback()
print "Error: %s" % e.args[0]
sys.exit(1)
finally:
if conn:
conn.close()
return settings
if __name__ == "__main__":
print initialize()
答案 0 :(得分:1)
依赖异常来检测表不存在是不可靠的,因为可能存在与您要检查的内容无关的其他错误。
确保创建表的最简单方法是在程序启动时执行CREATE TABLE IF NOT EXISTS ...
;如果表已经存在,这将被忽略。
要检查是否存在某些记录,使用SELECT就可以了。
但是,如果key
列上有UNIQUE或PRIMARY KEY约束,则可以执行INSERT OR IGNORE INTO Settings...
。
您不应在insert_defaults()
中使用单独的连接;如果你没有让你的交易提交正确,这将导致问题。