在Flask + SQLAlchemy中设置一对一的关系

5

我正在尝试建立两个表之间的关系,使我能够访问obj1.obj2.name,其中obj1是一个表,obj2是另一个表。这是一对一的关系(一个人对应一个地理区域)。

# Table one (Person)
class Person(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(100))
  region = db.Column(db.Integer, db.ForeignKey('region.id'))

# Table two (Region)
class Region(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(50))

如果我使用Person.region(其中Person是Person类的对象),我会得到用户区域主键的int值,但我想获取与其关联的“名称”字段。

我已经想出了以下解决方法:

region = models.Region.query.filter_by(id=REGION_ID).first().name

但在我的情况下不适用,因为我需要从Flask模板中访问“name”字段。有什么想法吗?

你是在查询 Person 中的 Person.region,还是在访问特定的人?也就是说,是使用 db.session.query(Person.region, etc...) 还是 person = Person.get_or_404(1); person.region - Sean Vieira
抱歉,我应该表述得更清楚。我正在尝试直接使用从Person类派生的对象进行工作。 - Delta
1个回答

7

这里基本上使用了您的模型,但是: 1)更改了FK列的名称 2)添加了一个relationship(请阅读文档的关系配置部分)

class Person(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))
    # @note: renamed the column, so that can use the name 'region' for
    # relationship
    region_id = db.Column(db.Integer, db.ForeignKey('region.id'))

    # define relationship
    region = db.relationship('Region', backref='people')


class Region(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))

通过这个,您可以获取以下地区的名称:
region_name = my_person.region.name  # navigate a 'relationship' and get its 'name' attribute

为了确保区域在与人员一起从数据库加载,可以使用 joinedload 选项:
p = (db.session.query(Person)
     .options(db.eagerload(Person.region))
     .get(1)
     )

print(p)
# below will not trigger any more SQL, because `p.region` is already loaded
print(p.region.name)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接