Python peewee save() не работает должным образом

Я вставляю / обновляю объекты в базу данных MySQL, используя peewee ORM для Python. У меня есть такая модель:

class Person(Model):
    person_id = CharField(primary_key=True)
    name = CharField()

Я создаю объекты / строки с помощью цикла, и каждый раз в цикле есть словарь:

pd = {"name":"Alice","person_id":"A123456"}

Затем я пытаюсь создать объект и сохранить его.

po = Person()
for key,value in pd.items():
    setattr(po,key,value)
po.save()

Это занимает некоторое время и выполняется без ошибок, но ничего не сохраняет в базу данных - записи не создаются.

Это работает:

Person.create(**pd)

Но также выдает ошибку (и завершает скрипт), когда первичный ключ уже существует. Прочитав инструкцию, я подумал save() была нужная мне функция - этот peewee будет выполнять обновление или вставлять по мере необходимости.

Не уверен, что мне нужно сделать здесь - попробуйте сначала получить каждую запись? Ловить ошибки и пытаться обновить запись, если она не может быть создана? Я новичок в peewee, и обычно просто пишу INSERT ... ON DUPLICATE KEY UPDATE или даже REPLACE,

4 ответа

Решение

У меня была возможность повторно проверить мой ответ, и я думаю, что его следует заменить. Вот образец, который я могу теперь рекомендовать; во-первых, используйте get_or_create() для модели, которая создаст строку базы данных, если она не существует. Затем, если он не создан (вместо этого объект извлекается из базы данных), установите все атрибуты из словаря данных и сохраните объект.

po, created = Person.get_or_create(person_id=pd["person_id"],defaults=pd)
if created is False:
    for key in pd:
        setattr(fa,key,pd[key])
    po.save()

Как и прежде, я должен упомянуть, что это две разные транзакции, поэтому их не следует использовать с многопользовательскими базами данных, требующими истинного обновления в одной транзакции.

Person.save(force_insert=True)

Это задокументировано: http://docs.peewee-orm.com/en/latest/peewee/models.html

Я думаю, вы могли бы попробовать get_or_create ()? http://peewee.readthedocs.org/en/latest/peewee/querying.html

Вы можете сделать что-то вроде:

      po = Person()
for key,value in pd.items():
    setattr(po,key,value)
updated = po.save()
if not updated:
    po.save(force_insert=True)
Другие вопросы по тегам