Внешний ключ к той же таблице в Python Peewee - PullRequest
0 голосов
/ 28 января 2020

Я использую ORM peewee для sqlite в Python. Я хотел бы создать таблицу Item с полем parent_id, которое будет внешним ключом для Item:

from peewee import *

db = SqliteDatabase("data.db")

class Item(Model):
    id = AutoField()
    parent_id = ForeignKeyField(Item, null = True)

    class Meta:
        database = db

db.create_tables([Item])

Однако существует ошибка из-за циклического внешнего ключа:

NameError: свободная переменная 'Item', на которую ссылается перед присваиванием в охватывающей области действия

Для этого случая в peewee есть DeferredForeignKey:

from peewee import *

db = SqliteDatabase("data.db")

class Item(Model):
    id = AutoField()
    parent_id = DeferredForeignKey("Item", null = True)

    class Meta:
        database = db

db.create_tables([Item])
Item._schema.create_foreign_key(Item.parent_id)

К сожалению, существует в sqlite нет ADD CONSTRAINT, поэтому появляется другая ошибка:

peewee.OperationalError: рядом с "CONSTRAINT": синтаксическая ошибка

Есть ли способ создания внешнего извещения введите sqlite, используя peewee, или я должен использовать простое целое число вместо внешнего ключа или использовать нативный SQL вместо ORM?

Ответы [ 2 ]

0 голосов
/ 29 января 2020

Это очень четко задокументировано: http://docs.peewee-orm.com/en/latest/peewee/models.html#self -referential-external-keys

Вы просто указали 'self' в качестве идентификатора:

class Item(Model):
    id = AutoField()
    parent = ForeignKeyField('self', backref='children', null=True)

    class Meta:
        database = db

Вы не нужно связываться с какими-либо отложенными ключами или чем-либо еще.

0 голосов
/ 28 января 2020

Я нашел решение. Пользовательские ограничения могут быть добавлены в Meta классе:

from peewee import *

db = SqliteDatabase("data.db", pragmas = {"foreign_keys": "on"})

class Item(Model):
    id = AutoField()
    parent_id = IntegerField()

    class Meta:
        database = db
        constraints = [
            SQL("FOREIGN KEY(parent_id) REFERENCES items(id)")
        ]

db.create_tables([Item])
...