一对一
我们将使用国家和首都来演示一对一关系:每个国家只有一个首都。反过来,一个城市也只能作为一个国家的首都。一对一关系如下:
在示例程序中,Country类表示国家,Capital类表示首都。建立一对一关系后,我们将在Country类中创建一个标量关系capital,调用它会获取单个Capital对象,我们还在Capital类中创建一个标量关系属性country,调用它会获取单个的Country对象。
一对一关系实际上是通过建立双向关系的一对多关系的基础上转化而来。我们要确保关系两侧的关系属性都是标量属性,都只返回单个值,所以要在定义集合属性的关系函数中将uselist参数设为False,这时一对多关系将被转换为一对一关系。下面代码基于建立双向关系的一对多关系实现了一对一关系。
app.py:建立一对一关系
class Country(db.Model): id = db.Column(db.Integer, primary_key = True) name = db.Column(db.String(30), unique = True) capital = db.relationship('Capital', uselist = False) def __repr__(self): return '<Country %r>' % self.name class Capital(db.Model): id = db.Column(db.Integer, primary_key = True) name = db.Column(db.String(30), unique = True) country_id = db.Column(db.Integer, db.ForeignKey('country.id')) country = db.relationship('Country') def __repr__(self): return '<Capital %r>' % self.name
“多”这一侧本身就是标量关系属性,不用做任何改动(有外键的是“多”这一侧),而“一”这一侧的集合关系属性,通过将uselist设为False后,将仅返回对应的单个记录,而且无法再使用列表语义操作
>>> china = Country(name = 'China') >>> beijing = Capital(name = 'Beijing') >>> db.session.add(china) >>> db.session.add(beijing) >>> db.session.commit() >>> china.capital >>> china.capital = beijing >>> china.capital <Capital u'Beijing'> >>> beijing.country >>> beijing <Capital u'Beijing'> >>> db.session.commit() >>> beijing <Capital u'Beijing'> >>> china.capital <Capital u'Beijing'> >>> china.capital.append('Tokyo') Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Capital' object has no attribute 'append'