簡體   English   中英

Python 帶有列名列表的 Sqlite3 插入操作

[英]Python Sqlite3 insert operation with a list of column names

通常,如果我想將值插入表中,我會做這樣的事情(假設我知道我想插入的值屬於哪些列):

conn = sqlite3.connect('mydatabase.db')
conn.execute("INSERT INTO MYTABLE (ID,COLUMN1,COLUMN2)\
VALUES(?,?,?)",[myid,value1,value2])

但是現在我有一個列列表(列表的長度可能會有所不同)和列表中每個列的值列表。

例如,如果我有一個包含 10 列的表(即 column1、column2...、column10 等)。 我有一個要更新的列列表。比方說[column3,column4] 我有這些列的值列表。 [value for column3,value for column4]

我如何將列表中的值插入到每個屬於的各個列中?

據我所知, conn.execute的參數列表僅適用於值,因此我們必須使用這樣的字符串格式:

import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE t (a integer, b integer, c integer)')
col_names = ['a', 'b', 'c']
values = [0, 1, 2]
conn.execute('INSERT INTO t (%s, %s, %s) values(?,?,?)'%tuple(col_names), values)

請注意,這是一次非常糟糕的嘗試,因為將始終檢查傳遞給數據庫的字符串是否受到注入攻擊。 但是,您可以在插入之前將列名列表傳遞給某些注入函數。

編輯:
對於各種長度的變量,您可以嘗試類似

exec_text = 'INSERT INTO t (' + ','.join(col_names) +') values(' + ','.join(['?'] * len(values)) + ')'
conn.exec(exec_text, values)
# as long as len(col_names) == len(values)

當然,字符串格式化將起作用,您只需要對此稍加精巧即可。

col_names = ','.join(col_list)
col_spaces = ','.join(['?'] * len(col_list))
sql = 'INSERT INTO t (%s) values(%s)' % (col_list, col_spaces)
conn.execute(sql, values)

我一直在尋找一種基於未知/可變長度列表創建列的解決方案,但發現了這個問題。 但是,我設法找到了一個更好的解決方案(無論如何對我來說),它也變得更現代了,所以我想將它包括進來,以防它對某人有所幫助:

import sqlite3

def create_sql_db(my_list):

    file = 'my_sql.db'
    table_name = 'table_1'
    init_col = 'id'
    col_type = 'TEXT'

    conn = sqlite3.connect(file)
    c = conn.cursor()

    # CREATE TABLE (IF IT DOESN'T ALREADY EXIST)
    c.execute('CREATE TABLE IF NOT EXISTS {tn} ({nf} {ft})'.format(
        tn=table_name, nf=init_col, ft=col_type))

    # CREATE A COLUMN FOR EACH ITEM IN THE LIST
    for new_column in my_list:
        c.execute('ALTER TABLE {tn} ADD COLUMN "{cn}" {ct}'.format(
            tn=table_name, cn=new_column, ct=col_type))

    conn.close()


my_list = ["Col1", "Col2", "Col3"]

create_sql_db(my_list)

我所有的數據都是文本類型的,所以我只有一個變量“ col_type”-但是,例如,您可以輸入一個元組列表(或元組的元組,如果您要輸入的內容):

my_other_list = [("ColA", "TEXT"), ("ColB", "INTEGER"), ("ColC", "BLOB")]

並將CREATE A COLUMN步驟更改為:

for tupl in my_other_list:

    new_column = tupl[0]   # "ColA", "ColB", "ColC"
    col_type = tupl[1]     # "TEXT", "INTEGER", "BLOB"

    c.execute('ALTER TABLE {tn} ADD COLUMN "{cn}" {ct}'.format(
        tn=table_name, cn=new_column, ct=col_type))

作為菜鳥,我無法評論@ron_g 提供的非常簡潔、更新的解決方案。 在測試時,盡管我不得不經常刪除示例數據庫本身,所以對於使用它進行測試的任何其他新手,我建議添加:

     c.execute('DROP TABLE IF EXISTS {tn}'.format(
    tn=table_name))

在“創建表...”部分之前。

似乎有多個實例

.format(
    tn=table_name ....)

在“CREATE TABLE ...”和“ALTER TABLE ...”中,因此試圖弄清楚是否可以創建單個實例(類似於或包含在 def 部分中)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM