• Flask默认并没有提供任何数据库操作的API,我们可以选择任何适合自己项目的数据库来使用。
  • Flask中可以自己的选择数据,用原生语句实现功能,也可以选择ORM(SQLALCHEMY、MongoEngine)。
  • 原生SQL缺点
    • 代码利用率低,条件复杂代码语句越长,有很多相似语句,一些SQL是在业务逻辑中拼出来的,修改需要了解业务逻辑,直接写SQL容易忽视SQL问题。
  • ORM
    • 将对对象的操作转换为原生SQL
    • 优点
      • 易用性,可以有效减少重复SQL
      • 性能损耗少
      • 设计灵活,可以轻松实现复杂查询
      • 移植性好
  • Python的ORM(SQLALCHEMY)
    • 针对于Flask的支持

SQLALCHEMY

中文文档

  • 安装
    • pip install flask-sqlalchemy
  • 数据库连接
  • dialect+driver://username:password@host:port/database
    • 数据库实现+数据库驱动://用户名:密码@主机名:端口/数据库名
  • 连接数据库需要指定配置
    • SQLALCHEMY_DATABASE_URI
    • SQLALCHEMY_TRAKE_MODIFICATIONS = False 禁止对象追踪修改

SQLite数据库连接不需要额外驱动,也不需要用户名密码

  • sqlite:///sqlite1.db
db = SQLAlchemy()
db.init_app(app)

数据库使用

  • 创建模型
class Persion(db.Model):
    __tablename__ = 'persion'
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(40),unique=True)
  • 创建数据库
    • db.create_all()
  • 删除数据库
    • db.drop_all()
  • 数据操作
    • 在事务中处理
    • 数据插入
      • db.session.add(object)
      • db.session.add_all(list[objet])
      • db.session.delete(object)
      • db.session.commit()
  • 修改和删除基于查询

常用约束

约束说明
primary_key主键
autoincremment自增
unique非空
index索引
nullable是否可空
default默认值
Foreign Key()外键

数据查询

  • 查询数据结果集
    • 语法:类名.query.**
  • 获取查询集
    • all() 以列表的形式返回此查询所表示的结果。这将导致底层查询的执行。
    • filter(类名.属性名.运算符(‘**’))
    • filter( 类名.属性名.运算符 值)
  • 运算符
运算符说明
contains
startswith
endswith
in_
like
__gt__
__ge__
__lt__
__le__
筛选说明
filter_by通过条件过滤
offset 对查询应用偏移量并返回新生成的查询。
limit 对查询应用一个限制并返回新生成的查询。
order_by 将一个或多个ORDER BY 标准应用于查询并返回新生成的查询。
get 返回基于给定主键标识符的实例,如果没有找到则返回None。
first 返回此查询的第一个结果,如果结果不包含任何行,则返回None。这将导致底层查询的执行。
paginate 从页页返回per_page项。默认情况下,如果没有找到任何项并且页面大于1,它将使用404中止。通过将error_out设置为False,可以禁用这种行为。
  • 逻辑运算
    • and_
    • filter(and_(条件),条件…)
    • or_
    • filter(or_(条件),条件…)
    • not_
    • filter(not_(条件),条件…)

数据库分页显示

class flask_sqlalchemy.BaseQuery(entitiessession=None)

  • SQLAlchemy查询子类,具有用于在web应用程序中查询的方便方法。
  • 这是用于模型的默认查询对象,并公开为query。通过子类化并设置query_class,覆盖单个模型的query类 。
  • first_or_404()
    • 与first()类似,但是如果没有找到,将中止并弹出 404 ,而不是返回None。
  • get_or_404(ident)
    • 与get()类似,但是如果没有找到,就会终止 并弹出 404 ,而不是返回None。
  • paginate(page=Noneper_page=Noneerror_out=Truemax_per_page=None)
    • 从 page page返回per_page 项。
    • 如果page或per_page为None,它们将从request query中检索。如果max_per_page是指定的,per_page会被限制在那个值。 如果没有请求,或者它们不在查询中,它们将默认分别为1和20.
    • 当error_out为True(默认)。以下规则将导致404响应:
      • 没有找到任何项,并且page不是1。
      • page小于1,或者per_page是负数。
      • page或per_page不是整形。
    • 当error_out是False,page和per_page分别默认为1和20.
    • 返回 Pagination  对象。

class flask_sqlalchemy.Pagination(querypageper_pagetotalitems)

  • BaseQuery.paginate() 返回的内部助手类 。 如果使用其他库,还可以从任何其他SQLAlchemy查询对象构造它。
  • 此外,可以将None作为查询对象传递,在这种情况下,prev()和next()将不再工作。
  • has_next
    • 如果存在下一页,则为真
  • has_prev
    • 如果前一页存在,则为真
  • items = None
    • 当前页的items
  • iter_pages(left_edge=2left_current=2right_current=5right_edge=2)
  • 遍历分页中的页码。这四个参数控制阈值,应该从侧面产生多少个数字。跳过的页码表示为None。这是你如何在模板中呈现这样的分页:
{% macro render_pagination(pagination, endpoint) %}
  <div class=pagination>
  {%- for page in pagination.iter_pages() %}
    {% if page %}
      {% if page != pagination.page %}
        <a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
      {% else %}
        <strong>{{ page }}</strong>
      {% endif %}
    {% else %}
      <span class=ellipsis>…</span>
    {% endif %}
  {%- endfor %}
  </div>
{% endmacro %}
  • next(error_out=False)
  • next_num
    • 下一页的编号
  • page = None
    • 当前页码(1索引)
  • pages
    • 总页数
  • per_page = None
    • 要显示在页面上的项数。
  • prev(error_out=False)
  • prev_num
    • 前页的编号。
  • query = None
    • 用于创建此分页对象的无限制查询对象。
  • total = None
    • 匹配查询的项的总数

发表回复