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

Del*_*lta 4 python mysql sqlalchemy

我正在尝试在两个表之间建立关系,这允许我到达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))
Run Code Online (Sandbox Code Playgroud)

如果我使用Person.region(其中Person是Person类的对象),我得到用户区域的主键的int,但我想得到与其关联的'name'字段.

我发现这会起作用:

region = models.Region.query.filter_by(id=REGION_ID).first().name
Run Code Online (Sandbox Code Playgroud)

但它不适用于我的情况,因为我需要从Flask模板访问'name'字段.

有什么想法吗?

van*_*van 7

这里我基本上使用你的模型,但是:1)更改了FK列的名称1)添加了一个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))
Run Code Online (Sandbox Code Playgroud)

有了这个,您可以获得该地区的名称,如下所示:

region_name = my_person.region.name  # navigate a 'relationship' and get its 'name' attribute
Run Code Online (Sandbox Code Playgroud)

为了确保在人员的同时从数据库加载区域,您可以使用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)
Run Code Online (Sandbox Code Playgroud)