flask 定义数据关系(多对一) --

多对一

一对多关系反过来就是多对一关系,这两种关系模式分别从不同的视角出发。一个作者拥有多篇文章,反过来就是多篇文章属于同一个作者。为了便于区分,我们使用居民和城市来演示多对一关系:多个居民住在同一个城市。多对一关系如下:

 

在例子中,Citizen类表示居民,City类表示城市。建立多对一关系后,我们将在Citizen类中创建一个标量关系属性city,调用它可以获取单个City对象。

我们在前面介绍过,关系属性在关系模式的出发侧定义。当出发点在“多”这一侧时,我们希望在Citizen类中添加一个关系属性city来获取对应的城市对象,因为这个关系属性返回单个值,我们称之为标量关系属性。在定义关系时,外键总是在“多”这一侧定义,所以在多对一关系中外键和关系属性都定义在“多”这一侧,即City类中:

app.py:建立多对一关系

class Citizen(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(70), unique = True)
    city_id = db.Column(db.Integer, db.ForeignKey('city.id'))
    city = db.relationship('City')

class City(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(30), unique = True)

这时定义的 city关系属性是一个标量关系(返回单一数据)。当Citizen.city被调用时,SQLAlchemy会根据外键字段city_id存储的值查找对应的City对象并返回,即居民记录对应的城市记录。

>>> from app import Citizen
>>> from app import db
>>> city1 = City(name = 'DaLian')
>>> citizen1 = Citizen(name = 'Xia')
>>> citizen1.city= city1
>>> citizen1.city
<City (transient 54277680)>

当建立双向关系时,如果不使用backref,那么一对多和多对一关系模式在定义上完全相同,这时可以将一对多和多对一关系模式。我们通常都会为一对多或多对一建立双向关系,这时将弱化这两种关系的区别,一律称为一对多关系。

class Citizen(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(70), unique = True)
    city_id = db.Column(db.Integer, db.ForeignKey('city.id'))
    city = db.relationship('City', back_populates='citizen')

    def __repr__(self):
        return '<Citizen %r>' % self.name

class City(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(30), unique = True)
    #back_populates的值为另一侧的关系属性名
    #relationship函数的第一个参数是另一侧的模型名(类型)
    citizen = db.relationship('Citizen', back_populates='city')


>>> from app import Citizen, City, db
>>> city1 = City(name = 'DaLian')
>>> citizen1 = Citizen(name = 'xiaxiaoxu')
>>> citizen2 = Citizen(name = 'xufengchai')
>>> citizen1.city = city1
>>> citizen2.city = city1
>>> city1.citizen
[<Citizen 'xiaxiaoxu'>, <Citizen 'xufengchai'>]
>>> citizen2.city
<City 'DaLian'>
>>> citizen1.city
<City 'DaLian'>
 
原文地址:https://www.cnblogs.com/xiaxiaoxu/p/10618343.html