1

私は小さなプロジェクトに取り組んでおり、カンマ区切りの値の文字列を値のようにデータベースに書き込むヘルパー関数を作成しました。このようにすることには意味があることは理解していますが、これは小さなことであり、より良くできるようになるまで続ける必要があります

def db_insert(table,data):
    """
    insert data into a table, the data should be a tuple
    matching the number of columns with null for any columns that
    have no value. False is returned on any error, error is logged to
    database log file."""

    if os.path.exists(database_name):
        con = lite.connect(database_name)

    else:
        error = "Database file does not exist."
        to_log(error)
        return False

    if con:
        try:
            cur = con.cursor()
            data = str(data)
            cur.execute('insert into %s values(%s)') % (table, data)
            con.commit()
            con.close()

        except Exception, e:
            pre_error = "Database insert raised and error;\n"
            thrown_error = pre_error + str(e)
            to_log(thrown_error)

        finally:
            con.close()


    else:
        error = "No connection to database"
        to_log(error)
        return False

database_name などは、スクリプトの別の場所で定義されています。

その他の明らかな明白なエラーを除きます。私ができる必要があるのは(この方法または提案がある場合は他の方法で)、各値が列の値を表すリストを誰かが作成できるようにすることです。いくつの列が入力されているかわかりません。

したがって、誰かが次のように使用します:
data = ["null", "foo","bar"]
db_insert("foo_table", data)

これにより、そのデータがテーブル名 foo_table に挿入されます。テーブル内の列数を把握し、それを満たす正しい数の要素を指定するのは、ユーザーの責任です。sqlite パラメータを使用した方がよいことは認識していますが、2 つの問題があります。まず、パラメーターを使用して値のみをテーブルに指定することはできません。2 つ目は、指定する値の数を知る必要があることです。あなたがしなければなりません;

cur.execute('insert into table values(?,?,?), val1,val2,val3)

3 つの ? を指定できる必要があります。任意の数の値を取り、それらを任意のテーブル名に挿入できる一般的な関数を作成しようとしています。今、値として「null」を渡そうとするまで、比較的問題なく動作していました。列の 1 つは主キーで、自動インクリメントがあります。したがって、null を渡すと、自動インクリメントが可能になります。null が必要になる他のインスタンスもあります。問題は、主キーが整数フィールドであるため、SQLite がデータ型の不一致として不平を言う単一引用符で python が null をラップし続けることです。None を python null に相当するものとして渡そうとすると、同じことが起こります。だから2つの問題。

任意の数の列を挿入する方法。
null を渡す方法。

この質問と過去の質問にご協力いただきありがとうございます。

申し訳ありませんが、これはこの Using Python quick insert many columns into Sqlite\Mysqlの複製のようです

申し訳ありませんが、これを書いた後まで見つけられませんでした。

結果は次のようになります。

def db_insert(table,data):
"""
insert data into a table, the data should be a tuple
matching the number of columns with null for any columns that
have no value. False is returned on any error, error is logged to
database log file."""

if os.path.exists(database_name):
    con = lite.connect(database_name)

else:
    error = "Database file does not exist."
    to_log(error)
    return False

if con:
    try:
        tuple_len = len(data)
        holders = ','.join('?' * tuple_len)

        sql_query = 'insert into %s values({0})'.format(holders) % table
        cur = con.cursor()
        #data = str(data)
        #cur.execute('insert into readings values(%s)') % table
        cur.execute(sql_query, data)
        con.commit()
        con.close()

    except Exception, e:
        pre_error = "Database insert raised and error;\n"
        thrown_error = pre_error + str(e)
        to_log(thrown_error)

    finally:
        con.close()


else:
    error = "No connection to database"
    to_log(error)
    return False
4

1 に答える 1

2

2番目の問題は、「私にとってはうまくいく」です。None を値として渡すと、その値をデータベースとの間で正しく変換します。

import sqlite3
conn = sqlite3.connect("test.sqlite")

data = ("a", None)
conn.execute('INSERT INTO "foo" VALUES(' + ','.join("?" * len(data)) + ')', data)

list(conn.execute("SELECT * FROM foo"))      # -> [("a", None)]
于 2012-10-22T18:06:54.673 に答える