根据id去查询 单个
class BookDetailResource(Resource):
def get(self, pk):
book = Book.query.get(pk)
book_fields = {
"id": fields.Integer,
"name": fields.String,
"sn": fields.String
}
return marshal(book, book_fields)
2、filter查询
SQLAlchemy 默认是懒惰模式,就是 如果不执行 all()、first()、get()就不会真正查询数据库。
-
如果我们filter查询 只想获取第一个 要使用first()
books = Book.query.filter(Book.name == name).first()
如果要所有查询结果
books = Book.query.filter(Book.name == name).all()3、filter_by查询
这个与filter查询区别是,一个查询方法名称不同。
一个查询的字段声明不同
判断条件不在是双等号== 而是 =等号
books = Book.query.filter_by(name = name).first()
books = Book.query.filter_by(name = name).all()4、比较运算符
对于 大于 等于 小于 这些 比较判断 我们要使用
例如
Book.id.__lt__(5) # 小于5 Book.id.__le__(5) # 小于等于5 Book.id.__gt__(5) # 大于5 Book.id.__ge__(5) # 大于等于5
books = Book.query.filter(Book.id.__lt__(5)).all()5、逻辑运算符
对于多条件的,或关系、与关系、非关系
or_ and_ not_
from sqlalchemy import or_, and_, not_ books = Book.query.filter(or_(Book.name == "红楼梦", Book.name == "水浒传")).all() books = Book.query.filter(and_(Book.sn == "10002", Book.name == "水浒传")).all() books = Book.query.filter(not_(Book.sn == "10002")).all()6、聚合函数
from sqlalchemy import func
func中 提供了 count、sum、avg 等 聚合函数
必须要使用 db.session 来查询
例如 统计所有图书的个数
r = db.session.query(func.count(Book.id)).all() print(r) # [(5,)]二、分页与排序 1、分页
分页的核心是,有一个start起始位置,count查询的个数
select * from 表 limit start,count
offset(start) 偏移量
limit(count) 查询几个
books = Book.query.offset(4).limit(2).all()
print("books:", books)
2、排序
books = Book.query.order_by(Book.id.asc()).all() books = Book.query.order_by(Book.id.desc()).all()三、一对多
我们以新闻表为例,定义两个表
新闻表:id、标题、内容、分类
分类表:id、分类名
在app.py文件中写入:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api,Resource,marshal,fields
app = Flask(__name__)
# 配置数据库
app.config["SQLALCHEMY_DATAbase_URI"] = "mysql://root:zf1234@127.0.0.1:3306/news"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config.update(RESTFUL_JSON={"ensure_ascii":False})
# 创建db对象 可以操作数据库
db = SQLAlchemy(app)
api = Api(app)
# 定义model类
# 一对多 定义两个表,分别为新闻表和分类表
# 分类表:id、分类名
class Type(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(20))
# 通过分类直接查询到所有新闻列表,反之,通过新闻表查询分类backref中定义分类
news_list = db.relationship("News",backref="type")
def __init__(self,name):
self.name = name
# 新闻表 id、标题、作者、内容
class News(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(20))
content = db.Column(db.Text)
type_id = db.Column(db.Integer,db.ForeignKey("type.id"))
# 定义一个接口
class TypeResource(Resource):
def get(self):
type = Type.query.get(1003)
# 根据分类查询该分类下的所有新闻
print(type.news_list)
# 根据新闻 找到对应的分类
print(type.news_list[0].type.name)
return marshal(type.news_list,{"title":fields.String,"content":fields.String})
api.add_resource(TypeResource,"/type")
新建一个任务管理器文件manager.py文件,写入:
# Manager管理,经营 Command 命令,指令
from flask_script import Manager,Command
# 导入app
from app import app,db
from flask_migrate import Migrate,MigrateCommand
# 创建一个命令管理器
manager = Manager(app)
# 要先把db给migrate框架
Migrate(app,db)
# 自定义一个命令--类
class AddCommand(Command):
def run(self):
print("我执行添加操作")
# 使用装饰器 来定义一个命令
@manager.command
def migrate():
print("我要执行数据库迁移")
db.create_all()
# 把命令添加到管理器 参数1:命令的别名
manager.add_command("add",AddCommand)
manager.add_command("db",MigrateCommand)
if __name__ == '__main__':
manager.run()
四、多对多
以文章为例,创建三个表
文章表:id、标题、内容
标签: id、名称
第三张表:文章表Id、标签ID
将我们上面的app.py改造一下
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restful import Api,Resource,marshal,fields
app = Flask(__name__)
# 配置数据库
app.config["SQLALCHEMY_DATAbase_URI"] = "mysql://root:zf1234@127.0.0.1:3306/news"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config.update(RESTFUL_JSON={"ensure_ascii":False})
# 创建db对象 可以操作数据库
db = SQLAlchemy(app)
api = Api(app)
# 定义model类
# 一对多 定义两个表,分别为新闻表和分类表
# 分类表:id、分类名
class Type(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
name = db.Column(db.String(20))
# 通过分类直接查询到所有新闻列表,反之,通过新闻表查询分类backref中定义分类
news_list = db.relationship("News",backref="type")
def __init__(self,name):
self.name = name
# 新闻表 id、标题、作者、内容
class News(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(20))
content = db.Column(db.Text)
type_id = db.Column(db.Integer,db.ForeignKey("type.id"))
# 定义一个接口
class TypeResource(Resource):
def get(self):
article = Article.query.get(1)
print(article.tags)
return "测试"
# type = Type.query.get(1003)
# print(type.news_list)
# print(type.news_list[0].type.name)
# return marshal(type.news_list,{"title":fields.String,"content":fields.String})
# 第三方
three_table = db.Table('article_tag',
db.Column('article_id',db.ForeignKey('article.id'),primary_key=True),
db.Column('tag_id',db.ForeignKey('tag.id'),primary_key=True))
# 文章表:id、标题、内容
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(20))
content = db.Column(db.Text)
tags = db.relationship('Tag', secondary=three_table, backref=db.backref('articles'))
# 标签: id、名称
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(20))
api.add_resource(TypeResource,"/type")



