模型继承与对应关系

2022-09-14 18:50:25 浏览数 (2)

一、模型继承

1、父类没有抽象化

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

代码语言:javascript复制
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Parent</span><span class="hljs-params">(db.Model)</span>:</span>
    __tablename__ = <span class="hljs-string">'parent'</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    uusername = db.Column(db.String(<span class="hljs-number">12</span>), default=<span class="hljs-string">'lucky'</span>)

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Son</span><span class="hljs-params">(Parent)</span>:</span>
    usex = db.Column(db.Boolean, default=<span class="hljs-keyword">True</span>)
    uage = db.Column(db.Integer, default=<span class="hljs-number">18</span>)

2、父类抽象化

Person父类

代码语言:javascript复制
<span class="hljs-keyword">from</span> exts <span class="hljs-keyword">import</span> db

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span><span class="hljs-params">(db.Model)</span>:</span>
    <span class="hljs-comment"># 父类抽象化</span>
    __abstract__ = <span class="hljs-keyword">True</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    name = db.Column(db.String(<span class="hljs-number">20</span>))
    age = db.Column(db.Integer)

子类 Man

代码语言:javascript复制
<span class="hljs-keyword">from</span> exts <span class="hljs-keyword">import</span> db
<span class="hljs-keyword">from</span> .animal <span class="hljs-keyword">import</span> Person

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Man</span><span class="hljs-params">(Person)</span>:</span>
    __tablename__ = <span class="hljs-string">"man"</span>
    weight = db.Column(db.Float)

子类 Women

代码语言:javascript复制
<span class="hljs-keyword">from</span> exts <span class="hljs-keyword">import</span> db
<span class="hljs-keyword">from</span> .animal <span class="hljs-keyword">import</span> Person

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Women</span><span class="hljs-params">(Person)</span>:</span>
    __tablename__ = <span class="hljs-string">"women"</span>
    height = db.Column(db.Float)

二、模型对应关系

1、一对多关系

新建one_to-many.py 代码如下

User模型类

代码语言:javascript复制
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span><span class="hljs-params">(db.Model, db.DBParent)</span>:</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    name = db.Column(db.String(<span class="hljs-number">50</span>))
    addresses = db.relationship(<span class="hljs-string">'Address'</span>, backref=<span class="hljs-string">'user'</span>,lazy=<span class="hljs-string">'dynamic'</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> self.name

Address模型类

代码语言:javascript复制
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Address</span><span class="hljs-params">(db.Model, db.DBParent)</span>:</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    detailed_address = db.Column(db.String(<span class="hljs-number">50</span>), default=<span class="hljs-string">'详细地址'</span>)
    user_id = db.Column(db.Integer, db.ForeignKey(<span class="hljs-string">'user.id'</span>))
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> self.detailed_address

代码说明

代码语言:javascript复制
addresses = db.relationship(<span class="hljs-string">'Address'</span>, backref=<span class="hljs-string">'user'</span>,lazy=<span class="hljs-string">'dynamic'</span>)
  • relationship函数 sqlalchemy对关系之间提供的一种便利的调用方式,关联不同的表
  • backref参数 对关系提供反向引用的声明,在Address类上声明新属性的简单方法,之后可以在my_address.user来获取这个地址的user
  • lazy参数 决定了 SQLAlchemy 什么时候从数据库中加载数据,有四个可选方式
    • select(默认值):SQLAlchemy 会在使用一个标准 select 语句时一次性加载数据
    • joined:让 SQLAlchemy 当父级使用 JOIN 语句是,在相同的查询中加载关系
    • subquery:类似 joined ,但是 SQLAlchemy 会使用子查询
    • dynamic:SQLAlchemy 会返回一个查询对象,在加载这些条目时才进行加载数据,大批量数据查询处理时推荐使用。
代码语言:javascript复制
user_id = db.Column(db.Integer, db.ForeignKey(<span class="hljs-string">'user.id'</span>))
  • ForeignKey参数 代表一种关联字段,将两张表进行关联的方式,表示一个User的外键,设定上必须要能在父表中找到对应的id值

一对多模型数据添加

代码语言:javascript复制
<span class="hljs-meta">@rel.route('/add_user/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_user</span><span class="hljs-params">()</span>:</span>
    u = User(name=<span class="hljs-string">'张三'</span>)
    u.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_user'</span>

<span class="hljs-meta">@rel.route('/add_address/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_address</span><span class="hljs-params">()</span>:</span>
	  <span class="hljs-comment"># 俩种添加方式都可以</span>
    <span class="hljs-comment"># a = Address(detailed_address='北京市昌平区', user_id=1)</span>
    <span class="hljs-comment"># a = Address(detailed_address='黑龙江省佳木斯市', user=User.query.get(1))</span>
    address = Address(detailed_address=<span class="hljs-string">'辽宁省沈阳市'</span>, user=User.query.get(<span class="hljs-number">2</span>))
    address.save()
    address.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_address'</span>

一对多模型数据查询

代码语言:javascript复制
<span class="hljs-comment"># 查看用户有哪些地址</span>
<span class="hljs-meta">@rel.route('/select_address/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">select_address</span><span class="hljs-params">()</span>:</span>
    u = User.query.filter_by(name=<span class="hljs-string">'lucky'</span>).first()
    print(u.addresses.all())
    <span class="hljs-keyword">return</span> <span class="hljs-string">'select_address'</span>

<span class="hljs-comment"># 查询地址所对应的用户</span>
<span class="hljs-meta">@rel.route('/select_user/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">select_user</span><span class="hljs-params">()</span>:</span>
    address = Address.query.first()
    print(address)
    <span class="hljs-keyword">return</span> <span class="hljs-string">'select_user'</span>

一对多数据删除

代码语言:javascript复制
<span class="hljs-comment"># 删除用户数据</span>
<span class="hljs-meta">@rel.route('/delete_user/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">delete_user</span><span class="hljs-params">()</span>:</span>
    u = User.query.first()
    u.delete()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'delete_user'</span>


<span class="hljs-comment"># 删除地址数据</span>
<span class="hljs-meta">@rel.route('/delete_address/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">delete_address</span><span class="hljs-params">()</span>:</span>
    address = Address.query.get(<span class="hljs-number">3</span>)
    address.delete()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'delete_address'</span>

2、一对一关系

新建one_to_one.py 代码如下

代码语言:javascript复制
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Wife</span><span class="hljs-params">(db.Model, db.DBParent)</span>:</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    name = db.Column(db.String(<span class="hljs-number">10</span>))
    husband = db.relationship(<span class="hljs-string">"Husband"</span>, backref=<span class="hljs-string">"wife"</span>, uselist=<span class="hljs-keyword">False</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> self.name


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Husband</span><span class="hljs-params">(db.Model, db.DBParent)</span>:</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    name = db.Column(db.String(<span class="hljs-number">10</span>))
    wife_id = db.Column(db.Integer, db.ForeignKey(<span class="hljs-string">'wife.id'</span>), unique=<span class="hljs-keyword">True</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> self.name

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

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

代码语言:javascript复制
<span class="hljs-comment"># 添加妻子数据</span>
<span class="hljs-meta">@oto.route('/add_wife/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_wife</span><span class="hljs-params">()</span>:</span>
    wife = Wife(name=<span class="hljs-string">'林心如'</span>)
    wife.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_wife'</span>


<span class="hljs-comment"># 添加丈夫数据</span>
<span class="hljs-meta">@oto.route('/add_husband/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_husband</span><span class="hljs-params">()</span>:</span>
    husband = Husband(name=<span class="hljs-string">'霍建华'</span>, wife=Wife.query.first())
    husband.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_husband'</span>

查询一对一数据

代码语言:javascript复制
<span class="hljs-comment"># 查询妻子的丈夫数据</span>
<span class="hljs-meta">@oto.route('/select_husband/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">select_husband</span><span class="hljs-params">()</span>:</span>
    w = Wife.query.first()
    print(w.husband)
    <span class="hljs-keyword">return</span> <span class="hljs-string">'select_husband'</span>


<span class="hljs-comment"># 查询丈夫的妻子数据</span>
<span class="hljs-meta">@oto.route('/select_wife/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">select_wife</span><span class="hljs-params">()</span>:</span>
    h = Husband.query.first()
    print(h.wife)
    <span class="hljs-keyword">return</span> <span class="hljs-string">'select_wife'</span>

3、多对多关系

新建many_to_many.py 代码如下

代码语言:javascript复制
tags = db.Table(<span class="hljs-string">'tags'</span>,
    db.Column(<span class="hljs-string">'tag_id'</span>, db.Integer, db.ForeignKey(<span class="hljs-string">'tag.id'</span>)),
    db.Column(<span class="hljs-string">'page_id'</span>, db.Integer, db.ForeignKey(<span class="hljs-string">'page.id'</span>))
)


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Page</span><span class="hljs-params">(db.Model, db.DBParent)</span>:</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    con = db.Column(db.String(<span class="hljs-number">200</span>), default=<span class="hljs-string">'页面内容'</span>)
    tags = db.relationship(<span class="hljs-string">'Tag'</span>, secondary=tags, backref=db.backref(<span class="hljs-string">'pages'</span>, lazy=<span class="hljs-string">'dynamic'</span>), lazy=<span class="hljs-string">'dynamic'</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> self.con


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Tag</span><span class="hljs-params">(db.Model, db.DBParent)</span>:</span>
    id = db.Column(db.Integer, primary_key=<span class="hljs-keyword">True</span>)
    name = db.Column(db.String(<span class="hljs-number">20</span>), default=<span class="hljs-string">'标签名'</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> self.name

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

代码说明

代码语言:javascript复制
tags = db.relationship(<span class="hljs-string">'Tag'</span>, secondary=tags, backref=db.backref(<span class="hljs-string">'pages'</span>, lazy=<span class="hljs-string">'dynamic'</span>))
  • secondary参数:指定多对多关系中关系表的名字
  • backref函数:由于在这里我们需要在每一页显示多个标签,所以使用backref参数添加一个反向引用,配置 Page.tags 加载后作为标签的列表

多对多模型数据添加

代码语言:javascript复制
<span class="hljs-comment"># 添加页面内容</span>
<span class="hljs-meta">@mtm.route('/add_pag/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_pag</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># page = Page(con='唐僧师徒四人为取真经,行至白虎岭前。在白虎岭内,住着一个尸魔白骨精...')</span>
    page = Page(con=<span class="hljs-string">'唐僧因悟空又打死拦路强盗,再次把他撵走。六耳猕猴精趁机变作悟空模样,抢走行李关文,又把小妖变作唐僧、八戒、沙僧模样...'</span>)
    page.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_pag'</span>
 
 
<span class="hljs-comment"># 添加标签</span>
<span class="hljs-meta">@mtm.route('/add_tag/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_tag</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># tag = Tag(name='孙悟空')</span>
    <span class="hljs-comment"># tag = Tag(name='猪八戒')</span>
    <span class="hljs-comment"># tag = Tag(name='真假美猴王')</span>
    tag = Tag(name=<span class="hljs-string">'西游记'</span>)
    tag.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_tag'</span>

多对多模型关系数据添加

代码语言:javascript复制
<span class="hljs-comment"># 添加模型对应关系数据</span>
<span class="hljs-meta">@mtm.route('/add_relationship/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">add_relationship</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># 查询第一页内容</span>
    page = Page.query.first()
    <span class="hljs-comment"># 给第一页添加第一个标签</span>
    <span class="hljs-comment"># page.tags.append(Tag.query.get(1))</span>
    <span class="hljs-comment"># 给第一页添加第四个标签</span>
    page.tags.append(Tag.query.get(<span class="hljs-number">4</span>))
    page.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'add_relationship'</span>

多对多模型数据查询

代码语言:javascript复制
<span class="hljs-comment"># 查询页面添加了哪些标签</span>
<span class="hljs-meta">@mtm.route('/select_pag/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">select_pag</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># 查询第一页内容的标签</span>
    page = Page.query.first()
    print(page.tags.all())
    <span class="hljs-keyword">return</span> <span class="hljs-string">'select_pag'</span>


<span class="hljs-comment"># 查询标签都被哪些页面添加了</span>
<span class="hljs-meta">@mtm.route('/select_tag/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">select_tag</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># 查询标签1都被哪个page添加了</span>
    tag = Tag.query.first()
    print(tag.pages.all())
    <span class="hljs-keyword">return</span> <span class="hljs-string">'select_tag'</span>

多对多模型数据删除

代码语言:javascript复制
<span class="hljs-comment"># 删除模型对应关系数据</span>
<span class="hljs-meta">@mtm.route('/delete_relationship_data/')</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">delete_relationship_data</span><span class="hljs-params">()</span>:</span>
    <span class="hljs-comment"># 第一页内容移除第一个标签</span>
    page = Page.query.first()
    page.tags.remove(Tag.query.get(<span class="hljs-number">1</span>))
    page.save()
    <span class="hljs-keyword">return</span> <span class="hljs-string">'delete_relationship_data'</span>

0 人点赞