阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

模型继承与对应关系

241次阅读
没有评论

共计 5333 个字符,预计需要花费 14 分钟才能阅读完成。

一、模型继承

1、父类没有抽象化

子类不会生成表,父类会生成表,并且将子类独有的字段放入父类表中

class Parent(db.Model):
__tablename__ = 'parent'
id = db.Column(db.Integer, primary_key=True)
uusername = db.Column(db.String(12), default='lucky')
class Son(Parent):
usex = db.Column(db.Boolean, default=True)
uage = db.Column(db.Integer, default=18)

2、父类抽象化

  • Person 父类

    from exts import db
    class Person(db.Model):
    # 父类抽象化
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    age = db.Column(db.Integer)
  • 子类 Man

    from exts import db
    from .animal import Person
    class Man(Person):
    __tablename__ = "man"
    weight = db.Column(db.Float)
  • 子类 Women

    from exts import db
    from .animal import Person
    class Women(Person):
    __tablename__ = "women"
    height = db.Column(db.Float)

二、模型对应关系

1、一对多关系

  • 新建 one_to-many.py 代码如下

    User 模型类

    class User(db.Model, db.DBParent):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    addresses = db.relationship('Address', backref='user',lazy='dynamic')
    def __str__(self):
    return self.name

    Address 模型类

    class Address(db.Model, db.DBParent):
    id = db.Column(db.Integer, primary_key=True)
    detailed_address = db.Column(db.String(50), default='详细地址')
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    def __str__(self):
    return self.detailed_address
  • 代码说明

    addresses = db.relationship('Address', backref='user',lazy='dynamic')
    
    • relationship 函数

      sqlalchemy 对关系之间提供的一种便利的调用方式,关联不同的表

    • backref 参数

      对关系提供反向引用的声明,在 Address 类上声明新属性的简单方法,之后可以在 my_address.user 来获取这个地址的 user

    • lazy 参数

      决定了 SQLAlchemy 什么时候从数据库中加载数据,有四个可选方式

      • select(默认值):SQLAlchemy 会在使用一个标准 select 语句时一次性加载数据
      • joined:让 SQLAlchemy 当父级使用 JOIN 语句是,在相同的查询中加载关系
      • subquery:类似 joined,但是 SQLAlchemy 会使用子查询
      • dynamic:SQLAlchemy 会返回一个查询对象,在加载这些条目时才进行加载数据,大批量数据查询处理时推荐使用。
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    
    • ForeignKey 参数

      代表一种关联字段,将两张表进行关联的方式,表示一个 User 的外键,设定上必须要能在父表中找到对应的 id 值

  • 一对多模型数据添加

    @rel.route('/add_user/')
    def add_user():
    u = User(name='张三')
    u.save()
    return 'add_user'
    @rel.route('/add_address/')
    def add_address():
    # 俩种添加方式都可以
    # a = Address(detailed_address='北京市昌平区', user_id=1)
    # a = Address(detailed_address='黑龙江省佳木斯市', user=User.query.get(1))
    address = Address(detailed_address='辽宁省沈阳市', user=User.query.get(2))
    address.save()
    address.save()
    return 'add_address'
  • 一对多模型数据查询

    # 查看用户有哪些地址
    @rel.route('/select_address/')
    def select_address():
    u = User.query.filter_by(name='lucky').first()
    print(u.addresses.all())
    return 'select_address'
    # 查询地址所对应的用户
    @rel.route('/select_user/')
    def select_user():
    address = Address.query.first()
    print(address)
    return 'select_user'
  • 一对多数据删除

    # 删除用户数据
    @rel.route('/delete_user/')
    def delete_user():
    u = User.query.first()
    u.delete()
    return 'delete_user'
    # 删除地址数据
    @rel.route('/delete_address/')
    def delete_address():
    address = Address.query.get(3)
    address.delete()
    return 'delete_address'

2、一对一关系

  • 新建 one_to_one.py 代码如下

    class Wife(db.Model, db.DBParent):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(10))
    husband = db.relationship("Husband", backref="wife", uselist=False)
    def __str__(self):
    return self.name
    class Husband(db.Model, db.DBParent):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(10))
    wife_id = db.Column(db.Integer, db.ForeignKey('wife.id'), unique=True)
    def __str__(self):
    return self.name

    在一对多关系基础上的父表中使用 backref 函数,并添加 uselist 参数来表示一对一关系

  • 添加数据以及模型对应关系数据

    # 添加妻子数据
    @oto.route('/add_wife/')
    def add_wife():
    wife = Wife(name='林心如')
    wife.save()
    return 'add_wife'
    # 添加丈夫数据
    @oto.route('/add_husband/')
    def add_husband():
    husband = Husband(name='霍建华', wife=Wife.query.first())
    husband.save()
    return 'add_husband'
  • 查询一对一数据

    # 查询妻子的丈夫数据
    @oto.route('/select_husband/')
    def select_husband():
    w = Wife.query.first()
    print(w.husband)
    return 'select_husband'
    # 查询丈夫的妻子数据
    @oto.route('/select_wife/')
    def select_wife():
    h = Husband.query.first()
    print(h.wife)
    return 'select_wife'

3、多对多关系

  • 新建 many_to_many.py 代码如下

    tags = db.Table('tags',
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
    db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
    )
    class Page(db.Model, db.DBParent):
    id = db.Column(db.Integer, primary_key=True)
    con = db.Column(db.String(200), default='页面内容')
    tags = db.relationship('Tag', secondary=tags, backref=db.backref('pages', lazy='dynamic'), lazy='dynamic')
    def __str__(self):
    return self.con
    class Tag(db.Model, db.DBParent):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), default='标签名')
    def __str__(self):
    return self.name

    如果想要用多对多关系,需要在两个类之间增加一个关联的辅助表

  • 代码说明

    tags = db.relationship('Tag', secondary=tags, backref=db.backref('pages', lazy='dynamic'))
    
    • secondary 参数:指定多对多关系中关系表的名字
    • backref 函数:由于在这里我们需要在每一页显示多个标签,所以使用 backref 参数添加一个反向引用,配置 Page.tags 加载后作为标签的列表
  • 多对多模型数据添加

    # 添加页面内容
    @mtm.route('/add_pag/')
    def add_pag():
    # page = Page(con='唐僧师徒四人为取真经,行至白虎岭前。在白虎岭内,住着一个尸魔白骨精...')
    page = Page(con='唐僧因悟空又打死拦路强盗,再次把他撵走。六耳猕猴精趁机变作悟空模样,抢走行李关文,又把小妖变作唐僧、八戒、沙僧模样...')
    page.save()
    return 'add_pag'
    # 添加标签
    @mtm.route('/add_tag/')
    def add_tag():
    # tag = Tag(name='孙悟空')
    # tag = Tag(name='猪八戒')
    # tag = Tag(name='真假美猴王')
    tag = Tag(name='西游记')
    tag.save()
    return 'add_tag'
  • 多对多模型关系数据添加

    # 添加模型对应关系数据
    @mtm.route('/add_relationship/')
    def add_relationship():
    # 查询第一页内容
    page = Page.query.first()
    # 给第一页添加第一个标签
    # page.tags.append(Tag.query.get(1))
    # 给第一页添加第四个标签
    page.tags.append(Tag.query.get(4))
    page.save()
    return 'add_relationship'
  • 多对多模型数据查询

    # 查询页面添加了哪些标签
    @mtm.route('/select_pag/')
    def select_pag():
    # 查询第一页内容的标签
    page = Page.query.first()
    print(page.tags.all())
    return 'select_pag'
    # 查询标签都被哪些页面添加了
    @mtm.route('/select_tag/')
    def select_tag():
    # 查询标签 1 都被哪个 page 添加了
    tag = Tag.query.first()
    print(tag.pages.all())
    return 'select_tag'
  • 多对多模型数据删除

    # 删除模型对应关系数据
    @mtm.route('/delete_relationship_data/')
    def delete_relationship_data():
    # 第一页内容移除第一个标签
    page = Page.query.first()
    page.tags.remove(Tag.query.get(1))
    page.save()
    return 'delete_relationship_data'

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-05-26发表,共计5333字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中