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

ego6inou  于 2022-11-30  发布在  SQLite
关注(0)|答案(4)|浏览(186)

通常,如果我想向表中插入值,我将执行类似以下的操作(假设我知道要插入的值属于哪些列):

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]
如何将列表中的值插入到各自所属的列中?

xn1cxnb4

xn1cxnb41#

据我所知,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)
pwuypxnk

pwuypxnk2#

当然,字符串格式也可以,只是需要更聪明一点。

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)
d8tt03nd

d8tt03nd3#

我正在寻找一个基于未知/可变长度列表创建列的解决方案,并发现了这个问题。然而,我设法找到了一个更好的解决方案(反正对我来说),它也更现代一点,所以我想我会包括它,以防它对某人有帮助:

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)

我的所有数据都是text类型,所以我只有一个变量“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))
sq1bmfud

sq1bmfud4#

作为一个新手,我不能对@罗恩_g提供的简洁的更新解决方案发表评论。在测试时,虽然我不得不频繁地删除示例数据库本身,所以对于其他使用这个来测试的新手,我建议添加:

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

在'CREATE TABLE...'部分之前。
似乎有多个

.format(
    tn=table_name ....)

在“CREATE TABLE...”和“ALTER TABLE...”中,因此尝试确定是否可以创建单个示例(类似于def节或包含在def节中)。

相关问题