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)