tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.55k stars 374 forks source link

Cyclic references support #379

Open Nenrikido opened 4 years ago

Nenrikido commented 4 years ago

Is your feature request related to a problem? Please describe. If we try to have cyclic referencing foreign keys, the schemas won't generate

Describe the solution you'd like Support cyclic references (can be extended to multiple references in general, with a support for reverse key chooses, like this )

Describe alternatives you've considered

grigi commented 4 years ago

The link you pointed to is something we already support, but we only specify a single side of the relation.

We can do an automatic resolver, but will have to add constraints later on, and we should not allow a CASCADE relationship that cycles the whole way else we risk deadlocking the database when an entry gets deleted.

As discussed, this will likely have to be supported when we address #8

tomhamiltonstubber commented 1 year ago

This seems like a limitation currently. If I'm correct, this won't work:

class User(AbstractUser):
    id = fields.IntField(pk=True)

    company = ForeignKeyField('models.Company', related_name='users')

class Company(Model):
    id = fields.IntField(pk=True)

    owner = ForeignKeyField('models.User', related_name='company', null=True)

This will raise an error despite the fact it should be very possible to create a Company, then a User.

merlinz01 commented 2 months ago

I would be eager to see this implemented.

As discussed, this will likely have to be supported when we address https://github.com/tortoise/tortoise-orm/issues/8

Looks like that issue is closed.

Until then, is there a workaround?

merlinz01 commented 1 month ago

OK, I found a way to work around this. This maybe could be helpful for whoever implements support for cyclic references.

  1. Comment out the foreign key fields in your models file, and insert temporary non-FK fields with the same types as would be auto-generated (with _id suffixes).
  2. Run aerich init-db or aerich migrate.
  3. Uncomment the foreign key fields and remove the temporary non-FK fields.
  4. Run aerich migrate.

In other words, add the foreign key constraint in a separate migration, and then aerich can handle it.