Целочисленный первичный ключ PeeWee требует force_insert=True

Я использую отличный модуль PeeWee для сохранения некоторых идентификаторов и имен хостов в таблице MySQL. Я хочу, чтобы «clientId» (который является IntegerField) был первичным ключом, но мне, кажется, нужно использовать save(force_insert=True), чтобы он вставлялся, иначе я ничего не добавляю в таблицу. Я не получаю никаких сообщений об ошибках. Я думал, что это должно быть необходимо только в том случае, если поле primary_key НЕ было целым числом. Я имею в виду документацию - (https://peewee.readthedocs.org/en/2.0.2/peewee/fields.html#non-integer-primary-keys)

Моя модель:-

class BaseModel(peewee.Model):
    class Meta:
        database = db

class Client(BaseModel):
    clientId = peewee.IntegerField(primary_key=True)
    clientName = peewee.TextField()
    isDeletedClient = peewee.BooleanField(default=False)

#Create object to insert using collected data...
clientEntry = Client(clientId=clientId, 
                     clientName=clientName, 
                     isDeletedClient=isDeletedClient)

#clientEntry.save()  # <-- Nothing gets inserted
clientEntry.save(force_insert=True)    # <-- Works.

person JazzyGeoff    schedule 15.10.2015    source источник
comment
То, как peewee определяет, следует ли выполнять INSERT или UPDATE, сводится к проверке того, равно ли значение первичного ключа None. Если нет, будет выполнена вставка, в противном случае будет обновлено существующее значение. Итак, ваше clientId равно None?   -  person Ivan Jovović    schedule 15.10.2015
comment
Привет, Джефф. Независимо от документов docs.peewee-orm.com/ en/latest/peewee/api.html#Model.save INSERT будет выдан независимо от того, существует первичный ключ или нет. Я думаю, вы пытались вставить запись с существующим первичным ключом. Вы можете попробовать первичный ключ с автоматическим увеличением docs.peewee-orm. com/en/latest/peewee/api.html#PrimaryKeyField   -  person discort    schedule 15.10.2015


Ответы (2)


Это тонкий момент, но если вы хотите автоматически увеличивать поля первичного ключа, вам следует использовать PrimaryKeyField, а не IntegerField(primary_key=True).

Это должно решить проблему:

class Client(BaseModel):
    clientId = peewee.PrimaryKeyField()
    clientName = peewee.TextField()
    isDeletedClient = peewee.BooleanField(default=False)
person coleifer    schedule 24.10.2015

Большое спасибо за ответ. Я считаю, что неправильно использовал метод save(). Вместо save(), который может выполнить обновление, если запись уже существует с первичным ключом, мне следовало использовать create(), потому что мой скрипт всегда создает новую пустую таблицу, а затем заполняет ее.

Итак, теперь моя модель остается прежней, но вставка строки становится...

clientEntry = Client.create(clientId=clientId, 
                            clientName=clientName,
                            isDeletedClient=isDeletedClient)
person JazzyGeoff    schedule 15.10.2015
comment
Это как-то неправильно. Да, create() вызывает save(force_insert=True), но вам не нужно этого делать. Если вы хотите, чтобы первичные ключи автоматически увеличивались, просто используйте PrimaryKeyField. - person coleifer; 24.10.2015
comment
Я уверен, что непреднамеренно ввел вас в заблуждение, но я не хотел «автоинкремента» для первичного ключа ClientId. ClientId — это целые числа, которые однозначно идентифицируют каждого «клиента», но я не хочу, чтобы БД назначала их, потому что я собираю их в своем скрипте как часть информации о клиенте. Я просто хотел, чтобы ClientId был первичным ключом, и обнаружил, что save() ничего не вставляет с моей исходной настройкой, потому что моя таблица каждый раз начинается пустой. - person JazzyGeoff; 26.10.2015
comment
Попался! Хорошо, тогда save(force_insert=True) или create() твои друзья :) - person coleifer; 28.10.2015