Skip to content

Commit 7e45ae3

Browse files
svlandegYuriiMotov
andauthored
Apply Yurii's rephrasing suggestions
Co-authored-by: Motov Yurii <[email protected]>
1 parent 4016556 commit 7e45ae3

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

docs/advanced/self-referential.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Self-referential relationships
22

3-
Oftentimes we need to model a relationship between one entity of some class and another entity (or multiple entities) of that **same** class. This is called a **self-referential** or **recursive** relationship. (The pattern is also sometimes referred to as an **adjacency list**.)
3+
Oftentimes we need to model a relationship between one entity of some class and another entity (or multiple entities) of that **same** class. This is known as a **self-referential** or **recursive** relationship, sometimes also called an **adjacency list**.
44

55
In database terms this means having a table with a foreign key reference to the primary key in the same table.
66

@@ -22,9 +22,13 @@ Using the `sa_relationship_kwargs` parameter, we pass the keyword-argument `remo
2222

2323
/// info
2424

25-
The SQLAlchemy documentation mentions this in passing, but crucially the `remote_side` value _"may be passed as a Python-evaluable string when using Declarative."_
25+
The `remote_side` parameter accepts a Python-evaluable string when using Declarative. This allows us to reference `Villain.id` even though the class is still being defined.
2626

27-
This allows us to pass the `id` field of the class we are just now defining as the remote side of that relationship.
27+
Alternatively, you can use a callable:
28+
29+
```py
30+
sa_relationship_kwargs={"remote_side": lambda : Villain.id}
31+
```
2832

2933
///
3034

@@ -34,9 +38,9 @@ Notice that we explicitly defined the relationship attributes we wanted for refe
3438

3539
For our purposes, it is necessary that we also provide the `back_populates` parameter to both relationships as explained in detail in a [dedicated chapter](../tutorial/relationship-attributes/back-populates.md){.internal-link target=_blank}.
3640

37-
In addition, the type annotations were made by enclosing our `Villain` class name in quotes, since we are referencing a class that is not yet fully defined by the time the interpreter reaches those lines. (See the chapter on [type annotation strings](../tutorial/relationship-attributes/type-annotation-strings.md){.internal-link target=_blank} for a detailed explanation.)
41+
In addition, the type annotations were made by enclosing our `Villain` class name in quotes, since we are referencing a class that is not yet fully defined by the time the interpreter reaches those lines. See the chapter on [type annotation strings](../tutorial/relationship-attributes/type-annotation-strings.md){.internal-link target=_blank} for a detailed explanation.
3842

39-
Finally, as with regular (i.e. non-self-referential) foreign key relationships, it is up to us to decide, whether it makes sense to allow the field to be **empty** or not. In our example, not every villain must have a boss. (In fact, we would otherwise introduce a circular reference chain, which would not make sense in this context.) Therefore we declare `boss_id: Optional[int]` and `boss: Optional['Villain']`. This is analogous to the `Hero``Team` relationship we saw [in an earlier chapter](../tutorial/relationship-attributes/define-relationships-attributes.md#optional-relationship-attributes){.internal-link target=_blank}.
43+
Finally, as with regular (i.e. non-self-referential) foreign key relationships, it is up to us to decide, whether it makes sense to allow the field to be **empty** or not. In our example, not every villain must have a boss (in fact, we would otherwise introduce a circular reference chain, which would not make sense in this context). Therefore we declare `boss_id: Optional[int]` and `boss: Optional['Villain']`. This is analogous to the `Hero``Team` relationship we saw [in an earlier chapter](../tutorial/relationship-attributes/define-relationships-attributes.md#optional-relationship-attributes){.internal-link target=_blank}.
4044

4145
## Creating instances
4246

0 commit comments

Comments
 (0)