tortoise / tortoise/tortoise-orm
Can't create schema due to cyclic fk references
Open
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 516
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 9
Description
"""
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the provided School, Student, and Principal example with SQLite and start at Tortoise.generate_schemas(), where the ConfigurationError is raised. Trace schema generation for the cyclic foreign keys; done means the example creates its schema without that error while preserving the declared relationships.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sqlite
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100