简体   繁体   English

Python Peewee 中同一个表的外键

[英]Foreign key to the same table in Python Peewee

I am using ORM peewee for sqlite in Python.我在 Python中将ORM peewee用于 sqlite。 I would like to create table Item with field parent_id that will be foreign key to the Item :我想创建带有字段parent_idItem ,它将是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])

However, there is error because of circular foreign key:但是,由于循环外键出现错误:

NameError: free variable 'Item' referenced before assignment in enclosing scope NameError:在封闭范围内赋值之前引用了自由变量“Item”

For this case, there is DeferredForeignKey in peewee:对于这种情况,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)

Unfortunately, there is no ADD CONSTRAINT in sqlite, so another error appears:不幸的是,sqlite中没有ADD CONSTRAINT ,所以出现了另一个错误:

peewee.OperationalError: near "CONSTRAINT": syntax error peewee.OperationalError:靠近“CONSTRAINT”:语法错误

Is there any way to create circural foreign key in sqlite using peewee, or I have to use plain integer instead of foreign key or use native SQL instead of ORM?有没有办法使用peewee在sqlite中创建循环外键,或者我必须使用普通整数而不是外键或使用本机SQL而不是ORM?

This is documented very clearly: http://docs.peewee-orm.com/en/latest/peewee/models.html#self-referential-foreign-keys这非常清楚地记录在案: http : //docs.peewee-orm.com/en/latest/peewee/models.html#self-referential-foreign-keys

You just put 'self' as the identifier:您只需将'self'作为标识符:

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

    class Meta:
        database = db

You do not need to mess with any deferred keys or anything.您不需要弄乱任何延迟密钥或任何东西。

I found solution.我找到了解决方案。 Custom constraints can be added in Meta class:可以在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])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM