一、模型继承
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 会返回一个查询对象,在加载这些条目时才进行加载数据,大批量数据查询处理时推荐使用。
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>