Let's consider 3 tables:
Each book has a foreign key to its author, which can either be in the American table, or the British one.
How can I implement such foreign key condition in SQLAlchemy?
I'd like to have a single column to handle the link.
My approach so far was to create an abstract class Author
, from which both AmericanAuthor
and BritishAuthor
inherit, and have the foreign key of Book
point to the parent.
class Author(Model):
__abstract__ = True
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
class AmericanAuthor(Author):
__tablename__ = 'american_author'
# some other stuff
class BritishAuthor(Author):
__tablename__ = 'british_author'
# some other stuff
class Book(Model):
__tablename__ = 'book'
title = db.Column(db.String)
author_id = db.Column(db.Integer, db.ForeignKey("author.id"))
It fails with the error:
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'books.author_id' could not find table 'author' with which to generate a foreign key to target column 'id'
Which completely makes sense, considering author
is abstract...
The FOREIGN KEY constraint is a key used to link two tables together.
A foreign key in SQL is a table-level construct that constrains one or more columns in that table to only allow values that are present in a different set of columns, typically but not always located on a different table.
How to Create a Table With Multiple Foreign Keys in SQL? When a non-prime attribute column in one table references the primary key and has the same column as the column of the table which is prime attribute is called a foreign key. It lays the relation between the two tables which majorly helps in the normalization of the tables.
The foreign key is the “joint” that connects together pairs of rows which have a relationship with each other, and SQLAlchemy assigns very deep importance to this concept in virtually every area of its operation.
In SQLAlchemy the key classes include ForeignKeyConstraintand Index. Defining Foreign Keys¶ A foreign keyin SQL is a table-level construct that constrains one or more columns in that table to only allow values that are present in a different set of columns, typically but not always located on a different table.
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Author.articles - there are no foreign keys linking these tables via secondary table ‘authorarticle’.
I think you can't build a relationship with two different tables using the same column.
Try creating two different columns ("american_author_id" and "british_author_id") then make a @property "author" that returns the author that isn't NULL.
This way you can get the author using: mybook.author
Although the @property
decorator will work in the application it might be better to use the @hybrid_property
from the sqlalchemy.ext.hybrid
package. In that way you will be able to filter on that property just like any normal attribute.
Your Book class would then look like:
class Book(Model):
__tablename__ = 'book'
title = db.Column(db.String)
american_author_id = db.Column(db.Integer, db.ForeignKey("american_author.id"), nullable=True)
british_author_id = db.Column(db.Integer, db.ForeignKey("british_author.id"), nullable=True)
@hybrid_property
def author_id(self):
return self.american_author_id or self.british_author_id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With