-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1039 Improve
LazyTableReference
(#1040)
* add test * improve lazy table refs * improve docs for `LazyTableReference` * add docs for circular imports
- Loading branch information
1 parent
85dd176
commit 76737dc
Showing
9 changed files
with
159 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
Avoiding circular imports | ||
========================= | ||
|
||
How Python imports work | ||
----------------------- | ||
|
||
When Python imports a file, it evaluates it from top to bottom. | ||
|
||
With :class:`ForeignKey <piccolo.columns.column_types.ForeignKey>` columns we | ||
sometimes have to reference tables lower down in the file (which haven't been | ||
evaluated yet). | ||
|
||
The solutions are: | ||
|
||
* Try and move the referenced table to a different Python file. | ||
* Use :class:`LazyTableReference <piccolo.columns.reference.LazyTableReference>` | ||
|
||
Import ``Table`` definitions as early as possible | ||
------------------------------------------------- | ||
|
||
In the entrypoint to your app, at the top of the file, it's recommended to | ||
import your tables. | ||
|
||
.. code-block:: python | ||
# main.py | ||
from my_app.tables import Manager, Band | ||
This ensures that the tables are imported, and setup correctly. | ||
|
||
Keep table files focused | ||
------------------------ | ||
|
||
You should try and keep your ``tables.py`` files pretty focused (i.e. | ||
just contain your ``Table`` definitions). | ||
|
||
If you have lots of logic alongside your ``Table`` definitions, it might cause | ||
your ``LazyTableReference`` references to evaluate too soon (causing circular | ||
import errors). An example of this is with | ||
:func:`create_pydantic_model <piccolo.utils.pydantic.create_pydantic_model>`: | ||
|
||
.. literalinclude:: avoiding_circular_imports_src/tables.py | ||
|
||
Simplify your schema if possible | ||
-------------------------------- | ||
|
||
Even with :class:`LazyTableReference <piccolo.columns.reference.LazyTableReference>`, | ||
you may run into some problems if your schema is really complicated. | ||
|
||
An example is when you have two tables, and they have foreign keys to each other. | ||
|
||
.. code-block:: python | ||
class Band(Table): | ||
name = Varchar() | ||
manager = ForeignKey("Manager") | ||
class Manager(Table): | ||
name = Varchar() | ||
favourite_band = ForeignKey(Band) | ||
Piccolo should be able to create these tables, and query them. However, some | ||
Piccolo tooling may struggle - for example when loading :ref:`fixtures <Fixtures>`. | ||
|
||
A joining table can help in these situations: | ||
|
||
.. code-block:: python | ||
class Band(Table): | ||
name = Varchar() | ||
manager = ForeignKey("Manager") | ||
class Manager(Table): | ||
name = Varchar() | ||
class ManagerFavouriteBand(Table): | ||
manager = ForeignKey(Manager, unique=True) | ||
band = ForeignKey(Band) |
22 changes: 22 additions & 0 deletions
22
docs/src/piccolo/tutorials/avoiding_circular_imports_src/tables.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# tables.py | ||
|
||
from piccolo.columns import ForeignKey, Varchar | ||
from piccolo.table import Table | ||
from piccolo.utils.pydantic import create_pydantic_model | ||
|
||
|
||
class Band(Table): | ||
name = Varchar() | ||
# This automatically gets converted into a LazyTableReference, because a | ||
# string is passed in: | ||
manager = ForeignKey("Manager") | ||
|
||
|
||
# This is not recommended, as it will cause the LazyTableReference to be | ||
# evaluated before Manager has imported. | ||
# Instead, move this to a separate file, or below Manager. | ||
BandModel = create_pydantic_model(Band) | ||
|
||
|
||
class Manager(Table): | ||
name = Varchar() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters