Python Sqlite3 insert operation with a list of column names

Question:

Normally, if i want to insert values into a table, i will do something like this (assuming that i know which columns that the values i want to insert belong to):

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

But now i have a list of columns (the length of list may vary) and a list of values for each columns in the list.

For example, if i have a table with 10 columns (Namely, column1, column2…,column10 etc). I have a list of columns that i want to update.Let’s say [column3,column4]. And i have a list of values for those columns. [value for column3,value for column4].

How do i insert the values in the list to the individual columns that each belong?

Asked By: Chris Aung

||

Answers:

As far as I know the parameter list in conn.execute works only for values, so we have to use string formatting like this:

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)

Please notice this is a very bad attempt since strings passed to the database shall always be checked for injection attack. However you could pass the list of column names to some injection function before insertion.

EDITED:
For variables with various length you could try something like

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)
Answered By: starrify

Of course string formatting will work, you just need to be a bit cleverer about it.

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)
Answered By: Daniel Roseman

I was looking for a solution to create columns based on a list of unknown / variable length and found this question. However, I managed to find a nicer solution (for me anyway), that’s also a bit more modern, so thought I’d include it in case it helps someone:

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)

All my data is of the type text, so I just have a single variable “col_type” – but you could for example feed in a list of tuples (or a tuple of tuples, if that’s what you’re into):

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

and change the CREATE A COLUMN step to:

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))
Answered By: ron_g

As a noob, I can’t comment on the very succinct, updated solution @ron_g offered. While testing, though I had to frequently delete the sample database itself, so for any other noobs using this to test, I would advise adding in:

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

Prior the the ‘CREATE TABLE …’ portion.

It appears there are multiple instances of

.format(
    tn=table_name ....)

in both ‘CREATE TABLE …’ and ‘ALTER TABLE …’ so trying to figure out if it’s possible to create a single instance (similar to, or including in, the def section).

Answered By: ts1g
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.