Published: October 11, 2021
Object inheritance is a staple in object-oriented-programming, but requires a bit of extra thought when applied with SQLAlchemy.
In this case, I have two distinct models which I want to inherit from a third, shared, parent.
Both: participant
and host
should inherit the majority of the their properties from the parent user
. In my instance, this allowed me to share some standard Flask-Login capabilities, but still decouple distinct logic between the models.
SQLAlchemy requires you to adopt one of three patterns outlined here: https://flask-login.readthedocs.io/en/latest/.
The above is implemented as an example of “Joined Table Inheritance”
In this case the database will have three tables to segment “users”:
users
table which will store the columns in the model definition for User
including the type
columnparticipant
table which will store the participant id
(which has a foreign key constraint to the user
table) and the specified attributes in the participant
model (e.g. email_address
)host
table which will store the host id
(which has a foreign key constraint to the user
table) and the specified attributes in the host
model (e.g. website
)For example:
username=peter
and email_address=peter@foo.bar
.user
table will have a row with two columns: id
: 1
, and type
: participant
participant
table will have a new row with two columns id
: 1
and email_address
: peter@foo.bar
(Note: both id
columns have the same value because of the foreign key constraint)
Users
will return both Participant
and Host
objectsParticipants
will return ony Participant
objects (and the same for Host
)The User
model requires:
...
type = Column(String(128), nullable=False)
...
__mapper_args__ = {
"polymorphic_identity": "user",
"polymorphic_on": type # Separate the different sub-models on the "type" column
}