• Flask 学习78.FlaskSQLAlchemy 一对多关系 上海


    前言

    一个人有多个收件地址,这就是一对多关系

    一对多(one-to-many)关系

    关系使用 relationship() 函数表示。然而外键必须用类 sqlalchemy.schema.ForeignKey 来单独声明:

    class Person(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(50))
        addresses = db.relationship('Address', backref='person',
                                    lazy='dynamic')
    
    class Address(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        email = db.Column(db.String(50))
        person_id = db.Column(db.Integer, db.ForeignKey('person.id'))
    

    db.relationship() 做了什么?
    这个函数返回一个可以做许多事情的新属性。在本案例中,我们让它指向 Address 类并加载多个地址。它如何知道会返回不止一个地址?
    因为 SQLALchemy 从您的声明中猜测了一个有用的默认值。 如果您想要一对一关系,您可以把 uselist=False 传给 relationship() 。

    那么 backref 和 lazy 意味着什么了?
    backref 是一个在 Address 类上声明新属性的简单方法。您也可以使用 my_address.person 来获取使用该地址(address)的人(person)。
    lazy 决定了 SQLAlchemy 什么时候从数据库中加载数据:

    • 'select' (默认值) 就是说 SQLAlchemy 会使用一个标准的 select 语句必要时一次加载数据。
    • 'joined' 告诉 SQLAlchemy 使用 JOIN 语句作为父级在同一查询中来加载关系。
    • 'subquery' 类似 'joined' ,但是 SQLAlchemy 会使用子查询。
    • 'dynamic' 在有多条数据的时候是特别有用的。不是直接加载这些数据,SQLAlchemy 会返回一个查询对象,在加载数据前您可以过滤(提取)它们。

    如何为反向引用(backrefs)定义惰性(lazy)状态?使用 backref() 函数:

    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
        name = db.Column(db.String(50))
        addresses = db.relationship('Address',
            backref=db.backref('person', lazy='joined'), lazy='dynamic')
    

    新增数据

    主表和关联表同时创建数据

        person = Person(name='yoyo')
        person.addresses = [
            Address(email='123@qq.com')
        ]
        db.session.add(person)
        db.session.commit()  # 提交
    

    如果先创建了person表数据

    person = Person(name='yoyo1')
    db.session.add(person)
    db.session.commit()  # 提交
    

    关联表根据查询对象再添加关联数据

        person = Person.query.filter_by(name='yoyo1').first()
        address = [
            Address(email='123@qq.com', person_id=person.id),
            Address(email='222@qq.com', person_id=person.id),
        ]
        db.session.add_all(address)
        db.session.commit()  # 提交
    

  • 相关阅读:
    Vue.js整理
    linux~dd命令
    linux 开机自启动的两种方式
    解决mount.nfs: access denied by server while mounting
    pip与apt-get的使用
    Mysql 中字符串的截取
    学生练习:括号匹配
    迷宫问题,打印所有路径,深度搜索,dfs
    vector用法
    【CF1257A】Two Rival Students【思维】
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/16729771.html
Copyright © 2020-2023  润新知