pthon-flask-数据库操作

Flask-SQLAlchemy的基本概念

  1. 什么是Flask-SQLAlchemy?
 - Flask-SQLAlchemy 是一个 Flask 扩展,简化了在 Flask 程序中使用 SQLAlchemy 的操作。
 - SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台。
 - SQLAlchemy 提供了高层 ORM,也提供了使用数据库原生 SQL 的低层功能。
  1. 如何安装Flask-SQLAlchemy?
    - pip install flask-sqlalchemy
  2. 如何配置数据库?
from flask_sqlalchemy import SQLAlchemy

basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
# sqlchemy将会追踪对象的修改并且发送信号
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
  1. 如何解决连接mysql数据库时的报错
import pymysql
pymysql.install_as_MySQLdb()

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:redhat@localhost/UserTest'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 实例化对象
db = SQLAlchemy(app)
  1. 如何定义模型?模型这个术语表示程序使用的持久化实体。
  • 模型列类型: 常用sql列属性
    在这里插入图片描述
    在这里插入图片描述
  1. 定义数据库模型:
class User(db.Model):
    # 默认情况下表名为类的名称, 如果想要重新设置表名, __tablename__
    # 类变量 __tablename__ 定义在数据库中使用的表名.
    __tablename__ = "用户信息"
    # db.Column 类构造函数的第一个参数是数据库列和模型属性的类型。
    # db.Column 中其余的参数指定属性的配置选项。
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30), unique=True, nullable=Flase)  # unique=True用户名不能重复
    password = db.Column(db.String(20), nullable=Flase)
    email = db.Column(db.String(20), unique=True)

数据表的创建删除及数据的增删改查

首先创建一个数据库UserTest;然后连接数据库,删除并创建数据表及对数据进行增删改查操作:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import  datetime

# **********************1. python3中MySQLdb报错解决方法********************
import pymysql

pymysql.install_as_MySQLdb()    
app = Flask(__name__)    
# **************************2. 数据库的配置与实例化****************************
# 对数据库操作(mysql, redis)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:redhat@localhost/UserTest'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 实例化对象
db = SQLAlchemy(app)
# ******************************3. 定义数据库模型********************************
# user ==== (id, username, password, email)
class User(db.Model):
    # 默认情况下表名为类的名称,如果想要重新设置表名,__tablename__
    __tablename__ = "用户信息"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30), unique=True, index=True, nullable=False)  # unique=True用户名不能重复
    password = db.Column(db.String(20), nullable=False)
    email = db.Column(db.String(20), unique=True, index=True)
    # 设置默认值,位当前用户的创建时间
    add_time = db.Column(db.DateTime, default=datetime.now() )


if __name__ == '__main__':

	# 每次实验之前删除上次实验的数据表    
    # 删除所有的表
    db.drop_all()
    
    # 创建所有的表
    db.create_all()

    # 插入数据(insert)
    u1 = User(username="粉条", password="westos", email="fentiao@qq.com")
    u2 = User(username="粉丝", password="westos", email="fensi@qq.com")
    db.session.add(u1)
    db.session.add(u2)
    db.session.commit()

    # 删除数据(delete)
    delete_user = User.query.filter_by(username="粉条").first()
    db.session.delete(delete_user)
    db.session.commit()

    # 更新数据(update)    
    update_user = User.query.filter_by(username="粉丝").first()
    print(update_user.email)
    print("正在更新邮箱地址.......")
    update_user.email = 'fensiupdate@qq.com'
    db.session.add(update_user)
    db.session.commit()
    print(update_user.email)

    # 查看数据(select)
    users = User.query.all()
    print(users)

关联数据库

from datetime import datetime
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import desc, func
import pymysql

pymysql.install_as_MySQLdb()
app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:redhat@localhost/UserTest'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)  
    
# 用户和角色是什么关系?
# 	一对多: 角色是一,用户是多,外键写在多的一端
class Role(db.Model):
    __tablename__ = "用户角色"
    # id号递增 autoincrement=True
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20))
    # 反向引用,Role表中有属性users,User类中有role这个属性
    users = db.relationship('User', backref='role')

    def __repr__(self):
        return "<Role %s>" % (self.name)


class User(db.Model):
    __tablename__ = "网站用户"
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30), unique=True, index=True, nullable=False)  # unique=True用户名不能重复
    password = db.Column(db.String(20), nullable=False)
    email = db.Column(db.String(20), unique=True, index=True)
    # 设置默认值,为当前用户的创建时间
    add_time = db.Column(db.DateTime, default=datetime.now())
    # 重要:用户角色id不能随便设置,需要从Role中查询(外键关联)
    role_id = db.Column(db.Integer, db.ForeignKey('用户角色.id'))

    # 定义了__repr()__ 方法,返回一个具有可读性的字符串表示模型,可在调试和测试时使用。
    def __repr__(self):
        return "<User %s>" % (self.username)


if __name__ == '__main__':
    db.drop_all()
    db.create_all()

    # ***********************1. 添加数据***********************
    # 1). 添加角色
    role1 = Role(name="普通用户")
    role2 = Role(name="会员")
    role3 = Role(name="管理员")

    db.session.add_all([role1, role2, role3])
    db.session.commit()
    
    # 2). 添加用户
    user1 = User(username="westos1", password="westos1", email="westos1@qq.com", role_id=1)
    
    db.session.add(user1)
    db.session.commit()

    # **********************2. 查看数据信息***********************
    print(User.query.all())
    print(Role.query.all())

    # 批量添加用户:100个普通用户,50个VIP用户,10个管理员
    # **********************批量添加数据***********************
    for item in range(100):
        user = User(
            username="fentiao%s" % (item),
            password="fentiao",
            email="fentiao%s" % (item),
            role_id=1
        )
        db.session.add(user)

    for item in range(50):
        user = User(
            username="vip%s" % (item),
            password="vip",
            email="vip%s" % (item),
            role_id=2
        )
        db.session.add(user)

    for item in range(10):
        user = User(
            username="admin%s" % (item),
            password="admin",
            email="admin%s" % (item),
            role_id=3
        )
        db.session.add(user)

    # 将批量添加的用户提交到数据库中
    db.session.commit()
   
    # **********************查看数据信息:过滤器查询**********************
    # filter_by过滤器的使用: 获取所有的普通用户、vip用户
    common_users = User.query.filter_by(role_id='1').all()
    print(common_users)
    vip_users = User.query.filter_by(role_id='2').all()
    print(vip_users)    
    # '获取所有的普通用户'转化成的sql语句并查看
    print(User.query.filter_by(role_id='1'))
    print(User.query)

    # filter过滤器的使用(更偏向于SQL语句,不建议使用)
    common_users = User.query.filter(User.role_id == 1).all()
    print(common_users)

    # limit过滤器: 只显示返回结果的前几条数据
    common_users_limit = User.query.filter(User.role_id == 1).limit(5).all()
    print(common_users_limit)

    # offset过滤器: 偏移显示
    common_users_offset = User.query.filter(User.role_id == 1).offset(2).limit(3).all()
    print(common_users_offset)

    # order_by排序过滤器: 默认是升序的,如果要降序 ----> desc(属性名)
    # 升序
    common_users_order = User.query.order_by(User.role_id).all()
    print(common_users_order)
    # 降序
    common_users_desc_order = User.query.order_by(desc(User.role_id)).all()
    print(common_users_desc_order)

    # group_by过滤器: 分组统计
    users_analysis = User.query.add_columns(func.count(User.role_id)).group_by(User.role_id).all()
    print(users_analysis)

查询过滤器总结:

在这里插入图片描述
在这里插入图片描述

# get方法
print(User.query.get(1))
# print(User.query.get_or_404(1000))

# count方法
print(User.query.filter_by(role_id=1).count())
print(User.query.filter_by(role_id=2).count())
print(User.query.filter_by(role_id=3).count())

分页对象(paginate)

在这里插入图片描述
在这里插入图片描述

# page=2: 要显示第2页的数据, per_page=5: 每页显示数据的条数
usersPageObj = User.query.paginate(page=2, per_page=5)

# *********************分页对象的属性*********************
print("当前页面的记录数:", usersPageObj.items)
print("分页查询的源sql语句:", usersPageObj.query)
print("当前显示的页数:", usersPageObj.page)
print("上一页的页数:", usersPageObj.prev_num)
print("下一页的页数:", usersPageObj.next_num)
print("是否包含上一页:", usersPageObj.has_prev)
print("是否包含下一页:", usersPageObj.has_next)
print("总页数:", usersPageObj.pages)
print("每页记录的数量:", usersPageObj.per_page)
print("记录总数:", usersPageObj.total)

# *********************分页对象的方法*********************
print("页码显示:", list(usersPageObj.iter_pages()))
print("上一页的数据:", usersPageObj.prev().items)
print("下一页的数据:", usersPageObj.next().items)

Flask-Script的基本概念

1.什么是Flask-Script?

Flask-Script用来生成shell命令,为在Flask里编写额外的脚本提供了支持。
这包括运行一个开发服务器,一个定制的Python命令行,用于执行初始化数据库、
    	定时任务和其他属于web应用之外的命令行任务的脚本。
Flask-Script和Flask本身的工作方式类似,只需要定义和添加能从命令行中被
    	Manager实例调用的命令即可。
  1. 为什么使用Flask-Script?
Flask的开发Web服务器支持很多启动设置选项,但只能在脚本中作为参数传给
	app.run()函数。这种方式很不方便,传递设置选项的理想方式是使用命令行参数。
Flask-Scrip就是这么一个Flask扩展,为Flask程序添加一个命令行解析器。
Flask-Script自带了一组常用选项,而且还支持自定义命令。
  1. 如何安装Flask-Script?
    pip install flask_script
  2. 如何配置Flask-Script?
    创建一个Python模块运行你的命令脚本。可以任意起名,例如 manage.py。
    无需把所有的命令都放在同一个文件里。例如,在一个大型项目中,可以把相关联的命令放在不同的文件里。
from flask_script import Manager

app = Flask(__name__)
# Manager类将追踪所有的在命令行中调用的命令和处理过程的调用运行情况
manager = Manager(app)

if __name__ == "__main__":
    # 将启动Manger实例接收命令行中的命令。
    manager.run()
实现功能
(2048) [root@foundation0 day36]# python manage.py 
usage: manage.py [-?] {shell,runserver} ...

positional arguments:
  {shell,runserver}
    shell            Runs a Python shell inside Flask application context.
    runserver        Runs the Flask development server i.e. app.run()  # 运行服务器, 可以指定host和端口
 1010  python manage.py  runserver 
 1011  python manage.py  runserver  -h
 1012  python manage.py  runserver  -h '0.0.0.0' -p 8089

optional arguments:
  -?, --help         show this help message and exit
  1. 添加自定义命令的3种方式:
网站参考: https://flask-script.readthedocs.io/en/latest/
    定义Command的子类
    使用command装饰器
    使用option装饰器
# 1. 方法一: 类的继承
class AddUser(Command):
    """添加用户"""
    def run(self):
        u = User(username="fentiao90009", password="fentiao", email="fentiao@qq.com")
        db.session.add(u)
        db.session.commit()
        return "正在添加用户%s........" % (u.username)
# 添加类到命令中, 让manger进行管理
database_manager.add_command('adduser', AddUser)


# 2. 通过装饰器@database_manager.command
@database_manager.command
def deleteUser():
    """删除用户"""
    u = User.query.filter_by(username='fentiao90009').first()
    if u:
        db.session.delete(u)
        db.session.commit()
        return "删除用户%s成功....." % (u.username)
    else:
        return "删除用户失败:"


# 3). option装饰器, 可以指定参数
@database_manager.option('-u', '--username', help="指定用户名")
@database_manager.option('-p', '--password', help="指定密码")
def add_user(username, password):
    """添加用户,指定用户名和密码"""
    if username and password:
        u = User(username=username, password=password)
        db.session.add(u)
        db.session.commit()
        return  "添加用户%s成功" %(u.username)
    else:
        return  "请指定用户名和密码"

Flask-Migrate的基本概念

  1. 什么是Flask-Migrate?
    Flask-Migrate是一个为Flask应用处理SQLAlchemy数据库迁移的扩展,使得可以通过Flask的命令行接口或者Flask-Scripts对数据库进行操作。
  2. 如何安装Flask-Migrate?
    pip install flask-migrate
  3. 如何配置?
app = Flask(__name__)

app.config.from_envvar('config.py')
db = SQLAlchemy(app) 

migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)
  1. 如何使用?
    1). 创建迁移仓库(migrations目录)

    python script.py db init

    2). 读取类的内容, 生成版本文件, 并没有真正在数据库中添加或删除;

    python script.py db migrate -m “版本名后缀”

    3). 在数据库中增删改, 也就是将迁移应用于数据库;

    python script.py db upgrade

    4). 检测是否成功?

    mysql -uroot -pwestos

    5). 去查看改变的历史状态;

    python script.py db history

    6). 返回指定的版本状态;降级数据库,不指定版本则是最老版本

    python script.py db downgrade base

    7). 显示当前版本

    python data_migrate.py db current

    8). 升级版本,不指定版本为最新版本

    python data_migrate.py db upgrade 版本号

    7). 帮助,查找所有命令

    python data_migrate.py db --help
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值