Вопрос

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?

Это было полезно?

Решение

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

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top