python - Flask-SQLAlchemy 和第三范式
问题描述
如何实现第 3 范式,例如Address
在 Flask-SQLAlchemy 中有一个单独的模型?开玩笑的是,我希望能够从多个不同的模型中使用这个单独的模型。
例如,假设我有两个不同的模型, aPerson
和 a Company
:
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
street_address = db.Column(db.Text, nullable=False)
postal_code = db.Column(db.Text, nullable=False)
city = db.Column(db.Text, nullable=False)
country = db.Column(db.Text, nullable=False)
# ...and so on
class Company(db.Model):
id = db.Column(db.Integer, primary_key=True)
street_address = db.Column(db.Text, nullable=False)
postal_code = db.Column(db.Text, nullable=False)
city = db.Column(db.Text, nullable=False)
country = db.Column(db.Text, nullable=False)
# ...and so on
现在这只是愚蠢的。地址不取决于它是个人还是公司。所以我可以制作一个单独的模型,如下所示:
class Address(db.Model):
id = db.Column(db.Integer, primary_key=True)
street_address = db.Column(db.Text, nullable=False)
postal_code = db.Column(db.Text, nullable=False)
city = db.Column(db.Text, nullable=False)
country = db.Column(db.Text, nullable=False)
然后将我的人物模型更改为:
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
address_id = db.Column(db.Integer, db.ForeignKey('address.id'), nullable=False)
# ...and so on
Address
然后添加对我的模型的反向引用:
class Address(db.Model):
id = db.Column(db.Integer, primary_key=True)
street_address = db.Column(db.Text, nullable=False)
postal_code = db.Column(db.Text, nullable=False)
city = db.Column(db.Text, nullable=False)
country = db.Column(db.Text, nullable=False)
person = db.relationship('Person', backref='address', lazy=True) # << NEW!
但是,现在我有一个设计可以Address
将Person
. 我希望所有可能需要地址的模型都能够使用该模型。我如何实现这一目标?
解决方案
您不应该添加relationship
on Address
。该表/模型与地址是 aPerson
还是 a无关Company
。
将关系添加到父母:
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
address_id = db.Column(db.Integer, db.ForeignKey('address.id'), nullable=False)
address = db.relationship(Address)
# ...and so on
与relationship
任何范式无关,它是为了协助 ORM 从查询结果创建 Python 对象,并且不会改变数据库的结构。将其添加到地址依赖于backref
使属性可用,这是不必要的模糊