24

I have a sqlite database with a table with following columns :

id(int) , name(text) , dob(text)

I want to insert following dictionary to it :

{"id":"100","name":"xyz","dob":"12/12/12"}

Dictionary keys are the column names. How can i achieve it ?

CharlesB
  • 86,532
  • 28
  • 194
  • 218
avee137
  • 421
  • 2
  • 7
  • 15
  • 5
    What have you tried? How are you connecting to the database? Are you using any kind of ORM? – pcalcao Jun 06 '12 at 11:19
  • Can you please provide some code you have Tried ?? – shobhit Jun 07 '12 at 10:23
  • you cannot insert a dictionary easily, but you can insert a list. Have a look [at the docs](https://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.executemany) – DJJ Feb 19 '15 at 11:21
  • A possible solution would be to modify the Class IterChars() in the [docs](https://docs.python.org/2/library[/sqlite3.html#sqlite3.Cursor.executemany) . I was not able to adapt it though. A look at [sqlalchemy](https://pypi.python.org/pypi/SQLAlchemy/1.0.0b4) might help as well – DJJ Mar 31 '15 at 20:46
  • Does this answer your question? [Insert Values from dictionary into sqlite database](https://stackoverflow.com/questions/25049332/insert-values-from-dictionary-into-sqlite-database) – wesinat0r Apr 07 '20 at 03:24

5 Answers5

17

To use dictionaries directly you can do:

user1 = {"id":100, "name": "Rumpelstiltskin", "dob": "12/12/12"}
c.execute("INSERT INTO users VALUES (:id, :name, :dob)", user1) 

Using along with instances/models:

class User:                                                                      

    def __init__(self, name, dob):                                            
        self.name = name                                                             
        self.dob = dao  

u1 = User("Rumpelstiltskin", "12/12/12")
c.execute("INSERT INTO users VALUES (:name, :dob)", u1.__dict__)

id is a keyword in Python, so if you want to use it as an identifier of an instance variable I would recommend using _id (and the same as your table's primary key name).

TMS
  • 301
  • 2
  • 7
14

Looking at the documentation here you can add a single row:

c.execute("INSERT INTO stocks VALUES (?,?,?)", [dict["id"], dict["name"], dict["dob"]])

Or you can use a list and add multiple rows in one go:

# Larger example that inserts many records at a time
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)
Pep_8_Guardiola
  • 5,002
  • 1
  • 24
  • 35
  • 2
    Maybe update this to show how a list of the asker's dictionaries can be inserted? With that I think your answer is better than mine. – Eliot Ball Jun 06 '12 at 11:46
9

Here's a way which preserves parameter safety. (Might need polishing in the tablename department)

def post_row(conn, tablename, rec):
    keys = ','.join(rec.keys())
    question_marks = ','.join(list('?'*len(rec)))
    values = tuple(rec.values())
    conn.execute('INSERT INTO '+tablename+' ('+keys+') VALUES ('+question_marks+')', values)

row = {"id":"100","name":"xyz","dob":"12/12/12"}
post_row(my_db, 'my_table', row)
himself
  • 4,806
  • 2
  • 27
  • 43
6

If, for example, c = conn.cursor(), and your dictionary is named dict and your table tablename, then you can write

c.execute('insert into tablename values (?,?,?)', [dict['id'], dict['name'], dict['dob']])

Which will insert the elements of the dictionary into the table as you require.

Eliot Ball
  • 698
  • 5
  • 11
1

As per Gareth‘s response, if you're using MySQLdb you can use executemany and pass a list of values which you can get directly from your dict using dict.values()

Daniel Bang
  • 715
  • 6
  • 21
  • 1
    Be careful to sort when using this method as the cursor will INSERT based on order and dictionaries do not maintain order. – Harrison Jun 25 '14 at 16:38
  • 2
    small update: Dictionaries now maintain order as of 3.6, and this behavior will be in language specification as of 3.7. – Yekta Leblebici Apr 27 '18 at 14:30