Question

How to save all instances in a single transaction in the peewee (python orm library)? For example:

from peewee import SqliteDatabase, Model, TextField

DB_NAME = 'users.db'
db = SqliteDatabase(os.path.join(os.path.dirname(__file__), DB_NAME))


class Users(Model):

    user_id = IntegerField(index = True)
    name = TextField(null = True, index = True)
    password = TextField(null = True)
    description = TextField(null = True)
    class Meta:
        database = db

if not Drugs.table_exists():
    Drugs.create_table()

data_to_save = [('user1', 'pass1'), ('user2', 'pass2'), ('user3', 'pass3')]

for user_name, user_password in data_to_save:
    user_data = Users.get_or_create(name=user_name, password=user_password)
    user_data.save()

how to rewrite in a single transaction?

Was it helpful?

Solution

You can wrap your query with "with" context manager https://docs.peewee-orm.com/en/3.4.0/peewee/transactions.html, so:

with db.transaction():
  for user_name, user_password in data_to_save:
    user_data = Users.get_or_create(name=user_name, password=user_password)
    user_data.save()

OTHER TIPS

Be warned. I think that you should be careful with the db.transaction() because as far as I've been playing with it, it's broken. It doesn't provide any transaction isolation by default. It's better to use direct database transactions for isolation. I'm so glad that I've seen these fails so many times, that I'm always writing test code to check out issues like these. And not blindly trusting bogus claims. This while using Python 3.4 and SQLite3. If you want isolation to work, it's better to use db.execute_sql('begin;') because it does work and creates required locks, even if those are deferred in this case aka, optimistic concurrency control.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top