那些年我们学Flask-SQLAlchemy,实现数据库操作,分页等功能

那些年我们学Flask-SQLAlchemy

实现数据库操作,分页等功能 


Flask-SQLAlchemy库让flask更方便的使用SQLALchemy,是一个强大的关系形数据库框架,既可以使用orm方式操作数据库,也可以使用原始的SQL命令.

Flask-Migrate 是一个数据迁移框架,需要通过Flask-script库来操作.

一.配置Flask-SQLAlchemy

程序使用的数据库地址需要配置在SQLALCHEMY_DATABASE_URI中,SQLALchemy支持多种数据库,配置格式如下:

  Postgres:

  postgresql://scott:[email protected]/mydatabase

  MySQL:

  mysql://scott:[email protected]/mydatabase

  Oracle:

  oracle://scott:[email protected]:1521/sidname

  SQLite:

  sqlite:////absolute/path/to/foo.db

db是SQLALchemy类的实例,表示程序使用的数据库,为用户提供Flask-SQLALchemy的所有功能

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
#配置数据库地址
app.config[‘SQLALCHEMY_DATABASE_URI‘] = ‘mysql://username:[email protected]:3306/DB_name?charset=utf8‘
#该配置为True,则每次请求结束都会自动commit数据库的变动
app.config[‘SQLALCHEMY_COMMIT_ON_TEARDOWN‘] = True
db = SQLAlchemy(app)
#也可以db = SQLAlchemy()      db.init_app(app)

二.定义模型

Flask-SQLALchemy使用继承至db.Model的类来定义模型,如:

class User(db.Model, UserMixin):#UserMixin是Flask-Login库中所需要的
    __tablename__ = ‘users‘
    #每个属性定义一个字段
    id = db.Column(db.Integer,primary_key=True)
    username = db.Column(db.String(64),unique=True)
    password = db.Column(db.String(64))

    #定制显示的格式    
    def __repr__(self):        
        return ‘<User %r>‘ % self.username

定义完需要在Python Shell中导入db,调用db.create_all()来创建数据库

(1)常用字段选项:

  primary_key 设置主键

  unique 是否唯一

  index 是否创建索引

  nullable 是否允许为空

  default 设置默认值,可以传入函数的引用 如传入 datetime.datetime.utcnow 则每次创建时时间都是最新时间

三.增删查改

(1) 插入数据:

from app.models import User
from app import db

#创建一个新用户
u = User()
u.username = ‘abc‘
u.password = ‘abc‘

#将用户添加到数据库会话中
db.session.add(u)

#将数据库会话中的变动提交到数据库中,如果不Commit,数据库中是没有改动的
db.commit()

(2)查找数据:

#返回所有用户保存到list中
user_list = User.query.all()

#查找username为abc的第一个用户,返回用户实例
u = User.query.filter_by(username=‘abc‘).first()

#模糊查找用户名以c结尾的所有用户
user_list  = User.query.filter(username.endswith(‘c‘)).all()

#查找用户名不是abc的用户
u = User.query.filter(username != ‘abc‘).first()

(3)删除数据:

user = User.query.first()
db.session.delete(user)
db.session.commit()

(4)修改数据:

u = User.query.first()
u.username = ‘Mackie‘
db.session.commit()

四.一对多关系

我的理解是:在多的一边定义外键,而relathonship()函数是用来建立关系的,可以只在一边定义,也可以两边都使用(只在一边使用时加上了backref选项等同于两边都使用)

class Person(db.Model):
        __tablename__ = ‘persons‘
        
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))    
    #backref将在Address表中创建个名为persons的Person引用,之后可以使用address.persons         #访问这个地址的所有人
    addresses = db.relationship(‘Address‘, backref=‘persons‘,lazy=‘dynamic‘)

class Address(db.Model):
        __tablename__ = ‘address‘
        
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(50))    
    #在多的一边使用db.ForeignKey声明外键
    person_id = db.Column(db.Integer, db.ForeignKey(‘person.id‘))

五.多对多关系

多对多关系可以分解为原表和关联表之间两个多对一关系,如下代码建立了学生与所选课程之间的关系:

#创建关联表,两个字段的外键是另两个表,一个学生对应多个关联表,一个关联表对应多个课程
registrations = db.Table(‘registrations‘,
                         db.Column(‘student_id‘,db.Integer,db.ForeignKey(‘students.id‘)),
                         db.Column(‘class_id‘,db.Integer,db.ForeignKey(‘classes.id‘))
                         )

class Student(db.Model):
    __tablename__ = ‘students‘
    id = db.Column(db.Integer,primary_key=True,)
    name = db.Column(db.String)
    classes = db.relationship(‘Class‘,
                              secondary = registrations, #关联表,只需要在一个表建立关系,sqlalchemy会负责处理好另一个表
                              backref = db.backref(‘students‘,lazy=‘dynamic‘),
                              lazy = ‘dynamic‘)

class Class(db.Model):
    __tablename__ = ‘classes‘
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)

多对多的使用:

#学生1增加一门选课student1.classes.append(class1)#学生1退选class1student1.classes.remove(class1)#学生1所选课程,由于指定了lazy=‘dynamic‘所以没有直接返回列表,而需要使用.all()student1.classes.all()

六.分页导航

Flask-SQLALchemy的Pagination对象可以方便的进行分页,

对一个查询对象调用pagenate(page, per_page=20, error_out=True)函数可以得到pagination对象,第一个参数表示当前页,第二个参数代表每页显示的数量,error_out=True的情况下如果指定页没有内容将出现404错误,否则返回空的列表

#从get方法中取得页码
page = request.args.get(‘page‘, 1, type = int)
#获取pagination对象
    pagination = Post.query.order_by(Post.timestamp.desc()).paginate(page, per_page=10, error_out = False)

#pagination对象的items方法返回当前页的内容列表
    posts = pagination.items

pagination对象常用方法:

has_next :是否还有下一页

has_prev :是否还有上一页

items : 返回当前页的所有内容

next(error_out=False) : 返回下一页的Pagination对象

prev(error_out=False) : 返回上一页的Pagination对象

page : 当前页的页码(从1开始)

pages : 总页数

per_page : 每页显示的数量

prev_num : 上一页页码数

next_num :下一页页码数

query :返回 创建这个Pagination对象的查询对象

total :查询返回的记录总数

iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2)

在模版中使用

方法一:

{% 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 %}

方法二:jinjia2渲染+bootstrap模板

<!-- 创建页码-->
<ul class="pagination">
{#上一页#}
    {%  if pagination.has_prev  %}
        <li><a href="{{ url_for(‘UserAdmin‘,page=pagination.prev_num) }}">&laquo;</a></li>
    {% endif %}

    {#页码#}
    {% set page_now = pagination.page  %}
    {% set page_count = pagination.pages %}
    {% if pagination.pages <= 5 %}
        {% for p in pagination.iter_pages() %}
                {% if p == pagination.page %}
                  <li ><a style="background-color: darkgray;opacity: 0.7;color: black" href="{{ url_for(‘UserAdmin‘,page=p) }}">{{ p }}</a></li>
                {% else %}
                    <li ><a href="{{ url_for(‘UserAdmin‘,page=p) }}">{{ p }}</a></li>
                {% endif %}
        {% endfor %}

        {% else %}
            {%  if page_now-2 >0 %}
                <li><a href="{{ url_for(‘UserAdmin‘,page=page_now-2) }}">{{ page_now-2 }}</a></li>
            {% endif %}
            {% if  page_now-1 >0  %}
                <li><a href="{{ url_for(‘UserAdmin‘,page=page_now-1) }}">{{ page_now-1 }}</a></li>
            {% endif %}
                <li ><a style="background-color: darkgray;opacity: 0.7;color: black" href="{{ url_for(‘UserAdmin‘,page=page_now) }}">{{ page_now }}</a></li>
            {% if (page_count-page_now) >1  %}
                <li><a href="{{ url_for(‘UserAdmin‘,page=page_now+1) }}">{{ page_now+1 }}</a></li>
            {% endif %}
            {% if (page_count - page_now) >2 %}
                <li><a href="{{ url_for(‘UserAdmin‘,page=page_now+1) }}">{{ page_now+2 }}</a></li>
            {% endif %}
    {% endif %}

{#下一页#}
    {%  if pagination.has_next  %}
        <li><a href="{{ url_for(‘UserAdmin‘,page=pagination.next_num) }}">&raquo;</a></li>
    {% endif %}

    <li><span style="color: black">页数 ( {{ page_now }}/{{ page_count }} )</span></li>
</ul>

效果展示:

时间: 2025-01-17 04:44:11

那些年我们学Flask-SQLAlchemy,实现数据库操作,分页等功能的相关文章

mongoose 数据库操作 - 分页

使用mongoose 添加分页方法,暂时还没发现什么更好的方法,我使用的方法是,直接在源码中添加 找到 node_modules/mongoose/lib/model.js打开这个文件,里面添加这段代码 /** * author:gtt * updateTime:2014-5-3 */ Model.execPageQuery = function find (currentPage,pageSize, conditions, fields, options, callback) { if ('f

flask学习之数据库操作一

数据库操作使用 sqlalchemy模块安装(需安装MySQL-python/python-devel) pip install flask-sqlalchemy 目录结构 ├── app │   ├── __init__.py │   └── models.py ├── config.py 配置环境 vim config.py #coding:utf-8 SQLALCHEMY_DATABASE_URI = 'mysql://mysqlTest:[email protected]/mysqlTe

Python框架学习之Flask中的数据库操作

数据库操作在web开发中扮演着一个很重要的角色,网站中很多重要的信息都需要保存到数据库中.如用户名.密码等等其他信息.Django框架是一个基于MVT思想的框架,也就是说他本身就已经封装了Model类,可以在文件中直接继承过来.但是在Flask中,并没有把Model类封装好,需要使用一个扩展包,Flask-SQLAlchemy.它是一个对数据库的抽象,让开发者不用这些编写SQL语句,而是使用其提供的接口去操作数据库,这其中涉及到一个非常重要的思想:ORM什么是ORM呢?下面我们就来详细讲解一下.

PHP数据库操作&amp;分页类

MySQL数据库操作类: 1 <?php 2 class mysql { 3 private $db_host; //数据库主机 4 private $db_user; //数据库用户名 5 private $db_pwd; //数据库用户名密码 6 private $db_database; //数据库名 7 private $conn; //数据库连接标识; 8 private $result; //执行query命令的结果资源标识 9 private $sql; //sql执行语句 10

十三、EnterpriseFrameWork框架核心类库之数据库操作(多数据库事务处理)

本章介绍框架中封装的数据库操作的一些功能,在实现的过程中费了不少心思,针对不同数据库的操作(SQLServer.Oracle.DB2)这方面还是比较简单的,用工厂模式就能很好解决,反而是在多数据库同时操作方面走了不少弯路:现在从以下几个方面进行说明: 一.不同数据库操作 此处用到了工厂模式来实现不同数据库操作,看下图 AbstractDatabase是一个抽象类,定义了所有对数据库的操作抽象方法,包括执行一个SQL语句.执行存储过程.事务操作等 [Serializable] public abs

Django数据库操作

刚学到Django的数据库操作,把它记录下来,方便以后查看: 在Django中定义数据库表,并使用Django提供的方法来对数据库进行操作(增.删.改.查) 1.定义3个数据库表: 1 class Group(models.Model): 2 name = models.CharField(max_length=50,default=None) 3 4 class User(models.Model): 5 name = models.CharField(max_length=50,defaul

循序渐进学.Net Core Web Api开发系列【9】:常用的数据库操作

系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇描述一些常用的数据库操作,包括:条件查询.排序.分页.事务等基本数据库操作.试验的数据库为MySQL. 二.条件查询1.查询所有记录 List<Article> articles = _context.Articles.ToList<Article>(); 2.根据主键进行查询 Articl

flask 数据库操作

说到flask中操作数据库首先要先引入一个概念:ORM ORM 全拼Object-Relation Mapping. 中文意为 对象-关系映射 其实它就是模型对象的概念,把数据库的信息映射成一个个对象来操作, 而不需要编写sql语句,简单来说就是面向对象编程的概念. flask 中的SQLAlchemy 就是一个ORM框架,它依赖于pymysql,使用关系对象映射对数据库进行操作 SQLAlchemy 的安装命令: pip install flask-sqlalchemy 下面就用代码展示使用S

flask sqlalchemy实现分页功能

接触到了一个新的实现分页的功能,记录下来 第一种方法:() flask sqlalchemy里面包括分页查询首先记录一下此方法实现分页查询: Post.query.paginate(1,10)    #第一个参数指示返回第几页的内容,第二页的参数表示每页展示的对象数量 Post.query.paginate(2,10)   #表示展示第二页数据,展示的对象是11~20个对象 不过,这种分页查询和.first(),.all()不同的是:它返回的是一个pagination对象 需要在前端页面中添加.