Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
circular
: A circular data dependency¶
An example of a restore.py
that abandoned before 20250731 because the
database contains a circular dependency. Since 20250731 Lino handles this
situation by saving “intermediate” model instances when appropriate.
Here is our models.py
file:
from lino.api import dd
class A(dd.Model):
b = dd.ForeignKey('circular.B', related_name="a2b", blank=True, null=True)
class B(dd.Model):
a = dd.ForeignKey('circular.A', related_name="b2a", blank=True, null=True)
And a demo fixture:
from lino.api import rt
def objects():
A = rt.models.circular.A
B = rt.models.circular.B
yield (a := A())
yield (b := B(a=a))
a.b = b
yield a
These two database rows exist, and Lino can dump them, but the dump wasn’t able to load before 20250731.
>>> from lino import startup
>>> startup('lino_book.projects.circular.settings')
>>> from lino.api.doctest import *
>>> from atelier.sheller import Sheller
>>> dbhash.check_virgin()
>>> shell = Sheller(settings.SITE.project_dir)
>>> assert (shell.cwd / 'manage.py').exists()
>>> shell("django-admin ddt -b")
...
Writing /.../circular/tmp/a/restore.py...
...
There are 2 models with circular dependencies :
- circular.A (1 rows, depends on circular.B)
- circular.B (1 rows, depends on circular.A)
Wrote 2 objects to /.../circular/tmp/b/restore.py and siblings.
Successfully ran double-dump test in /.../circular/tmp.
Restore database state (dbhash doesn’t work after above snippet because the old database is still loaded):
>>> shell("django-admin prep -b")
...
`initdb demo` started on database /.../circular/default.db.
...
Installed 3 object(s) from 1 fixture(s)
Note that it reports 3 (not 2) objects. That’s because the A instance is being yielded twice.