Biggen
Biggen

Reputation: 295

Peewee and Inserts with lists

I'm confused on how to insert a list of tuples into the db using Peewee. My db is setup as follows:

class Stats(Model):
    name = TextField(index=True)
    gender = TextField()
    age = TextField()
    city = TextField()
    state = TextField()

    class Meta:
        database = db

My list of tuples looks like this:

records = [("Joe Smoe", "Male", 34, "Joe City", "Joe State")],
          [("Jane Doe", "Female", 21, "Jane City", "Jane State")]

Do I iterate over the list inserting one row at a time? Can this be bulk inserted or does it need to be made into a dict to do that?

Upvotes: 1

Views: 2207

Answers (2)

Ben Hoyt
Ben Hoyt

Reputation: 11044

You can iterate over the list and insert one row at a time, but it's much better and significantly more efficient to use peewee's Model.insert_many function to do a bulk insert with a single SQL INSERT statement. And yes, per those API docs, insert_many() requires a list (or any iterable) of dict objects, each of which must have the same keys.

You can do this manually, like so:

rows = [
    {"name": "Joe Smoe", "gender": "Male", "age": 34,
     "city": "Joe City", "state": "Joe State"},
    {"name": "Jane Doe", "gender": "Female", "age": 21,
     "city": "Jane City", "state" :"Jane State"},
    ...
]
Stats.insert_many(rows)

Or if you already have a list of records tuples like you've shown in your question, you can use Model._meta.sorted_field_names to iterate over the Stats model's field names to build the dicts:

# Be sure to exclude the implicit primary key field
fields = [name for name in Stats._meta.sorted_field_names if name != 'id']
rows = [dict(zip(fields, record)) for record in records]
Stats.insert_many(rows)

Upvotes: 3

Biggen
Biggen

Reputation: 295

I ended up just taking the individual lists and using dict comp on them to convert them into a dict for insertion. So it looked something like this:

name_list = ['Joe Smoe', 'Jane Doe']
gender_list = ['male', 'female']
age_list = [34, 21]
city_list = ['Joe City', 'Jane City']
state_list = ['Joe State', 'Jane State']

completed_dict = [{
                 'name': a, 'gender': b, 'age': c, 'city': d, 'state': e}
                 for a, b, c, d, e, in zip(name_list, gender_list,  age_list, city_list, state_list)]

with db.atomic():
    Stats.insert_many(completed_dict).execute()

Not sure if this was the best way to do it, but it worked just fine for me.

Upvotes: 1

Related Questions