Sqlite3:使用try:except:建立db表&默认数据集 - 犹太教?

时间:2013-11-23 17:57:22

标签: python-2.7 sqlite

我已经为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()
  • 埃里克

1 个答案:

答案 0 :(得分:1)

依赖异常来检测表不存在是不可靠的,因为可能存在与您要检查的内容无关的其他错误。

确保创建表的最简单方法是在程序启动时执行CREATE TABLE IF NOT EXISTS ...;如果表已经存在,这将被忽略。

要检查是否存在某些记录,使用SELECT就可以了。 但是,如果key列上有UNIQUE或PRIMARY KEY约束,则可以执行INSERT OR IGNORE INTO Settings...

您不应在insert_defaults()中使用单独的连接;如果你没有让你的交易提交正确,这将导致问题。