Open zooyf opened 1 year ago
""" This example shows how relations between models especially unique field work. Key points in this example are use of ForeignKeyField and OneToOneField has to_field. For other basic parts, it is the same as relation example. """ from tortoise import Tortoise, fields, run_async from tortoise.models import Model from tortoise.query_utils import Prefetch class School(Model): uuid = fields.UUIDField(pk=True) name = fields.TextField() id = fields.IntField(unique=True) prime_student: fields.ForeignKeyRelation["Student"] = fields.ForeignKeyField( "models.Student", related_name="prime_student", to_field="id" ) students: fields.ReverseRelation["Student"] principal: fields.ReverseRelation["Principal"] class Student(Model): id = fields.IntField(pk=True) name = fields.TextField() school: fields.ForeignKeyRelation[School] = fields.ForeignKeyField( "models.School", related_name="students", to_field="id" ) prime_student: fields.ReverseRelation[School] class Principal(Model): id = fields.IntField(pk=True) name = fields.TextField() school: fields.OneToOneRelation[School] = fields.OneToOneField( "models.School", related_name="principal", to_field="id" ) async def run(): await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}) await Tortoise.generate_schemas() school1 = await School.create(id=1024, name="School1") student1 = await Student.create(name="Sang-Heon Jeon1", school_id=school1.id) student_schools = await Student.filter(name="Sang-Heon Jeon1").values("name", "school__name", "school__id") print(student_schools[0]) await Student.create(name="Sang-Heon Jeon2", school=school1) school_with_filtered = ( await School.all() .prefetch_related(Prefetch("students", queryset=Student.filter(name="Sang-Heon Jeon1"))) .first() ) school_without_filtered = await School.first().prefetch_related("students") print(len(school_with_filtered.students)) print(len(school_without_filtered.students)) school2 = await School.create(id=2048, name="School2") await Student.all().update(school=school2) student = await Student.first() print(student.school_id) await Student.filter(id=student1.id).update(school=school1) schools = await School.all().order_by("students__name") print([school.name for school in schools]) fetched_principal = await Principal.create(name="Sang-Heon Jeon3", school=school1) print(fetched_principal.name) fetched_school = await School.filter(name="School1").prefetch_related("principal").first() print(fetched_school.name) if __name__ == "__main__": run_async(run())
Cycle fk in sql is ok, but not on tortoise-orm.
I simply added a prime_student in School and the same in Student, but it raise an Error
tortoise.exceptions.ConfigurationError: Can't create schema due to cyclic fk references
See https://github.com/tortoise/tortoise-orm/issues/379#issuecomment-2251271197 for a workaround.
Cycle fk in sql is ok, but not on tortoise-orm.
I simply added a prime_student in School and the same in Student, but it raise an Error
tortoise.exceptions.ConfigurationError: Can't create schema due to cyclic fk references