当前位置:   article > 正文

Python全栈:Flask的ORM使用_python flask orm

python flask orm

1 ORM是什么

  • ORM(Object Relational Mapping),对象关系映射

ORM的重要特性:

  • 面向对象的编程思想,方便扩充
  • 少写(几乎不写)SQL,提升开发效率
  • 支持多种类型的数据库,方便切换
  • ORM技术成熟,能解决绝大部分问题

2 flask-sqlalchemy介绍及安装、配置

安装

image-20210202085514314

  • 安装

pip安装:pip install -U Flask-SQLAlchemy

源码安装:python setup.py install

  • 安装依赖

pip install mysqlclient

fask-sqlalchemy配置

  • 数据库URI:SQLALCHEMY_DATABASE_URI

    统一资源标识符(Uniform resource Identifier,∪R|)是一个用于标识某一互联网资源名称的字符串

  • MySQL数据库URL参数格式

    mysql: //scott: tiger@localhost/mydatabase

image-20210202105834588

  • 多个数据库支持
SQLALCHEMY_BINDS = {
	'db1':'mysqldb://localhost/users',
	'db2':'sqlit:path/to/appmeta.db'
}
  • 1
  • 2
  • 3
  • 4

创建数据库

image-20210202110409737

3 设计数据库模型并创建表

数据库模型设计:

  • 绑定到Fask对象

    db = SQLAlchemy(app)

  • ORM模型创建

    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
    
    • 1
    • 2
  • 指定表名称

    __tablename__ = 'weibo_user_addr'
    
    • 1

创建和删除表:

  • 手动创建数据库

  • 创建表

    db.create_all(bind='db1')

  • 删除表

    db.drop_all()

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 配置数据库的连接参数
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root@127.0.0.1/test_flask'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), nullable=False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

image-20210202111832736

数据库模型设计:

  • ORM模型字段类型支持

image-20210202112027548

  • 一对多关系,外键关联
user_id = db.Column(db.Integer, db.ForeignKey('weibo_user.id'), nullable=False)
  • 1
  • 一对多关系,外键关联
user = db.relationship('User', backref=db.backref('address', lazy=True))
  • 1
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 配置数据库的连接参数
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root@127.0.0.1/test_flask'
db = SQLAlchemy(app)


class User(db.Model):
    __tablename__ = 'weibo_user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), nullable=False)
    password = db.Column(db.String(256), nullable=False)
    birth_date = db.Column(db.Date, nullable=True)
    age = db.Column(db.Integer, default=0)


class UserAddress(db.Model):
    """ 用户的地址 """
    __tablename__ = 'weibo_user_addr'
    id = db.Column(db.Integer, primary_key=True)
    addr = db.Column(db.String(256), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('weibo_user.id'), nullable=False)
    user = db.relationship('User', backref=db.backref('address', lazy=True))


@app.route('/')
def mine():
    """  首页 """
    return render_template('index.html')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

4 使用OR M插入、修改、删除数据

新增/修改数据

  • 构造ORM模型对象

    usr = User('admin','admin@exapmle.com)

  • 添加到db.session(备注:可添加多个对象)

    db.session.add(user)

  • 提交到数据库

    db.session.commit()

新增用户

image-20210202121557723

新增第二个

image-20210202121648678

新增第三个

image-20210202121714133

数据库结果:

image-20210202121733862

修改:

image-20210202122033120

物理删除数据:

  • 查询ORM模型对象

    user = User.query.filter_by(username='zhangsan').first()

  • 添加到db.session

    db.session.delete(user)

  • 提交到数据库

    db.session.commit()

5 使用ORM进行数据查询与展示

  • 返回结果集(list)

    • 查询所有数据

      User.query.all()

    • 按条件查询

      User.query.filter_by(username='zhangsan')

      User.query.filter(User.nickname.endswith('三')).all()

    • 排序

      User.query.order_by(User.username)

    • 查询TOP10

      User.query.limit(10).all()

image-20210202122950560

  • 返回单个ORM对象

    • 更具PK(主键)查询

      User.query.get(1)

    • 获取第一条记录

      User.query.first()

  • 视图快捷函数:有则返回,无则返回404

    • first() vs first_or_404()
    • get() vs get_or_404()
  • 多表关联查询

    • db.session.query(User).join(Address)
    • User.query.join(Address)

分页:

  • 方式一:使用offset和limit
    • .offset(offset).limit(limit)
  • 方式二:paginate分页支持
    • .paginte(page=2,per_page=4)
    • 返回Pagination的对象

Pagination的对象:

  • has_prev/has_next——是否有上一页/下一页

  • Items——当前页的数据列表

  • prev_num/next_num——上一页/下一页的页码

  • total——总记录数

  • pages——总页数

结合模板实现分页:

  • 第一步:准备数据

    list_user = User.query.filter_by(is_valid=1)

  • 第二步:分页

    list_user.paginate(page=2, per_page=4)

  • 第三步:在模板中实现分页操作

app.py

from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# 配置数据库的连接参数
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@127.0.0.1/test_flask'
db = SQLAlchemy(app)


class User(db.Model):
    __tablename__ = 'weibo_user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), nullable=False)
    password = db.Column(db.String(256), nullable=False)
    birth_date = db.Column(db.Date, nullable=True)
    age = db.Column(db.Integer, default=0)


class UserAddress(db.Model):
    """ 用户的地址 """
    __tablename__ = 'weibo_user_addr'
    id = db.Column(db.Integer, primary_key=True)
    addr = db.Column(db.String(256), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('weibo_user.id'), nullable=False)
    user = db.relationship('User', backref=db.backref('address', lazy=True))

@app.route('/user/<int:page>/')
def list_user(page):
    """ 用户分页 """
    per_page = 10 # 每一页的数据大小
    # 1. 查询用户信息
    user_ls = User.query
    # 2. 准备分页的数据
    user_page_data = user_ls.paginate(page, per_page=per_page)
    return render_template('list_user.html', user_page_data=user_page_data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

list_user.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户分页操作</title>
</head>
<body>
<h3>总共有{{ user_page_data.total }}用户,当前在第{{ user_page_data.page }}页用户, 总共{{ user_page_data.pages }}页</h3>
<p>
    用户列表:

<ul>
    {% for user in user_page_data.items %}
    <li>{{ user.username }} - {{ user.password }}</li>
    {% endfor %}
</ul>
{% if user_page_data.has_prev %}
<a href="{{ url_for('list_user', page=user_page_data.prev_num) }}">上一页</a>
{%  endif %}
{% if user_page_data.has_next %}
<a href="{{ url_for('list_user', page=user_page_data.next_num) }}">下一页</a>
{% endif %}
</p>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/521937
推荐阅读
相关标签
  

闽ICP备14008679号