sqlite _delete ='CASCADE'上的PYTHON PEEWEE不起作用

4ioopgfo  于 2022-12-13  发布在  SQLite
关注(0)|答案(2)|浏览(207)

我有一个表,它有一个引用另一个表的ForeignKeyField。通过使用on_delete参数初始化ForeignKeyField,可以支持ON DELETE功能。虽然不太清楚on_delete可以取什么值,但文档中给出了一个示例,例如'CASCADE'。尽管如此,on_delete='CASCADE'似乎没有作用,因为试图从父表之一删除行会引发错误。
以下示例不起作用:

import peewee

db = peewee.SqliteDatabase("base.db")

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

class Grades(BaseModel):
    year = peewee.IntegerField()
    division = peewee.CharField(max_length=1)

class Student(BaseModel):
    dni = peewee.IntegerField()
    name = peewee.CharField(max_length=40)
    surname = peewee.CharField(max_length=40)
    gender = peewee.CharField(max_length=1)
    grade = peewee.ForeignKeyField(Grades, on_delete="CASCADE")

我希望删除年级时,该年级的学生也会被删除

9udxz4iz

9udxz4iz1#

当创建表时,CASCADE需要到位,Sqlite也必须配置为PRAGMA foreign_keys=1,例如

db = SqliteDatabase('...', pragmas={'foreign_keys': 1})

同时满足这两个条件时,删除对应学生时,删除成绩,如:

db = SqliteDatabase(':memory:', pragmas={'foreign_keys': 1})                             

class Student(db.Model):
    name = TextField()

class Grade(db.Model):
    student = ForeignKeyField(Student, on_delete='CASCADE')                              
    value = TextField()

db.create_tables([Student, Grade])
s1, s2 = Student.create(name='s1'), Student.create(name='s2')                            
Grade.create(student=s1, value='A')
Grade.create(student=s2, value='F')
s1.delete_instance()
for g in Grade:
    print(g.value)

印刷品:

F
uubf1zoe

uubf1zoe2#

ForeignKeyField建构函式中的on_delete参数会指定当删除父数据表中的数据列时,包含外部索引键之数据表中的数据列应该发生的动作。on_delete的可能值为:
CASCADE:此选项将删除表中具有引用父表中已删除行的外键的所有行。
SET NULL:此选项会在删除父表格中的数据列时,将表格中具有外部索引键之数据列的外部索引键设定为NULL。
RESTRICT:如果表中有任何行的外键引用了父表中的行,则此选项将阻止删除父表中的行。
设置默认值:当删除父表中的行时,此选项会将表中具有外键的行中的外键设置为外键定义中指定的默认值。
无动作:删除父表格中的数据列时,此选项不会对表格中具有外部索引键的数据列执行任何动作。
在您的程式码中,您使用了on_delete的CASCADE选项,这表示应该删除Student数据表中指涉Grades数据表中已删除数据列的任何数据列。但是,这并不会发生,因为您实际上并未删除Grades数据表中的任何数据列。

相关问题