Flask数据库操作
一、MySQL数据库安装(我用的是解压版)
- 解压:将下载的zip包解压到任意目录;
- 配置环境变量:将解压后的文件夹中的bin目录路径放入环境变量的path中;
- 配置文件:在解压的文件夹下(也就是bin的上一级目录)新建一个ini配置文件如“my-default.ini”(如果有就是修改其中的内容),在配置文件中写入(修改或追加)如下内容:
[mysqld]
basedir=D:\MySQL Server 8.0
datadir=D:\MySQL Server 8.0\data
注:解压后可自己更改文件夹名称,比如我这儿是“MySQL Server 8.0”,配置这两个信息后,其中的“data”文件夹不要自己创建(默认是没有这个文件夹的,但是会在下一步自动创建),否则MySQL服务会启动失败。
- 安装MySQL服务:在DOS窗口cd到bin目录,依次执行命令“mysqld -install”和“mysqld --initialize-insecure”(第二个命令会自动创建data文件夹,里面包含数据库的一些基本信息,并且该命令执行成功后不会返回任何信息);
- 启动(停止)MySQL服务:执行命令“net start mysql”启动MySQL服务(停止服务是“net stop mysql”);
- 设置密码:重开DOS窗口(保证是管理者权限),执行命令“mysqladmin -u root -p password”,回车,显示“Enter password”,不用输入任何东西直接回车(未设置密码时默认没有密码),显示“New password”,输入自己的密码即可,回车,显示“Confirm new password”,再次输入密码即可,回车,设置密码成功;
- 登录:输入命令“mysql -u root -p”,回车,然后输入设置的密码即可。
安装和使用过程中遇到的问题和解决方案:
- 使用命令“mysql -u root -p”输入密码后提示“access denied for user root @localhost(using password:YES)”,进不去数据库:删除全部文件夹重新安装“MySQL安装(解压版)”,重新设置一遍密码就OK了(关键是网上找了许多办法也不管用,只能这招了)。
- 运行Flask连接数据库时提示“Client does not support authentication protocol requested by server; consider upgrading MySQL client”:进入数据库后依次执行命名“USE mysql;”、“ALTER USER ‘root‘@‘localhost‘ IDENTIFIED WITH mysql_native_password BY ‘123456‘;”和“FLUSH PRIVILEGES;”,其中除了“‘123456‘”是个人设置的密码外,其他的字母和字符都copy就行了(第二条命令执行失败的话,重新进入数据库或者重新安装数据库再试一下吧,我第一次也没成功,后来重设密码后又成功了)。
二、插件安装(MySQL-python和SQLAlchemy)
- MySQL-python安装(连接数据库的驱动插件)
- 在网址https://www.lfd.uci.edu/~gohlke/pythonlibs/下载对应Python(32位或64位)的MySQL-python包;
- 进入Python的虚拟环境并启动(此插件我是安装在虚拟环境中的);
- cd到下载包的目录,并执行命令“pip install [包名]”即可。
- 注:直接在虚拟环境中使用“pip install mysql-python”会出错,貌似这个中间件不支持windows,所以需要下载一个非官方的中间件。
2. SQLAlchemy安装(实现Flask的ORM(Object Relationship Mapping模型关系映射)框架的插件)
-
- 在(虚拟)环境中执行命令“pip install flask-sqlalchemy”即可。
三、SQLAlchemy使用(以下方括号表示可以自定义)
1. 基础使用
i. 配置:需要在配置文件中配置数据库连接字符串“SQLALCHEMY_DATABASE_URI”;
# 数据库连接固定格式格式字符串 # dialect+driver://username:[email protected]:port/database DIALECT = ‘mysql‘ DRIVER = ‘mysqldb‘ USERNAME = ‘root‘ PASSWORD = 123456 HOST = ‘127.0.0.1‘ PORT = ‘3306‘ DATABASE = ‘db_demo1‘ SQLALCHEMY_DATABASE_URI = ‘{dialect}+{driver}://{username}:{password}@{host}:{port}/{database}?charset=utf8‘.format( dialect=DIALECT, driver=DRIVER, username=USERNAME, password=PASSWORD, host=HOST, port=PORT, database=DATABASE )
ii. 实例化:实例化一个SQLAlchemy对象,需要使用一个Flask对象作为参数传入,如果实例化的时候不传入,可以在需要的时候使用init_app(flask_obj)方法传入;
iii. db.create_all():是将加载的(未加载的不会生效)class模型在数据库中生成对应的表;
iv. class模型:需要继承db.Model,对应数据库中的表,一个class实例对应一条记录;
v. db.Column:class模型中需要使用“db.Column”来指定数据库中相应的列;
vi. __tablename__:对应数据库中的表名,若未指定此变量的值,则使用class模型类名的全小写作为表名。
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app) db.create_all() class User(db.Model): __tablename__ = ‘user‘ # 设置表名,未设置则以类名全小写为表名 id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 定义列id,整型,主键,自增长 username = db.Column(db.String(100), nullable=False) # 定义列username,字符型(最大100个字符),非空
2. SQLAlchemy中的db.Column属性(列)定义
-
- db.Integer:整型;
- db.String(max_length):可变字符串类型,需要执行字符串最大长度;
- db.Text:“text”类型;
- db.ForeignKey(‘[table_name].[attr_name]‘):表明此列引用另外一张的某一列作为外键,参数为字符串类型,字符串中是表名和列名;
- primary_key:取值“True/False”,是否为主键;
- nullable:取值“True/False”,是否允许为空;
- autoincrement:取值“Ture/False”,是否为自增长。
3. SQLAlchemy的增、删、改、查和提交事务
-
- 增:实例化模型类(将各个属性的值作为参数传进去),然后使用用“db.session.add([model_class_obj])”;
- 查:使用“[model_class_obj].query.filter([model_class_obj].[attr_name] == [value]).first()”,“filter()”中传入查询条件,可根据需要定义筛选条件,“filter()”的结果是一个“Query”对象,效果就像Python的列表,“first()”返回的是查询结果的第一条数据(如果有,没有就返回None),还可以使用“all()”返回结果的列表,其中每一个元素就是一个实例对象,也可以使用下标的形式“[index]”,但是下标的形式在没有结果数据的情况下会报错;
- 改:直接将查询出来的结果对象的属性重新赋值就可以了;
- 删:使用“db.session.delete([query_result_obj])”删除查询出的结果对象即可;
- 提交事务:任何对数据库的修改操作都需要提交,否则无法在数据库中生效,使用“db.session.commit()”即可。
4. SQLAlchemy的关系建立
-
- 关系变量db.relationship(‘[model_class_name]‘, secondary=[middle_table_name], backref=db.backref(‘[model_class_list_name]‘)):第一个参数为另一个表的模型类名称,secondary为指定多对多关系中的中间表,在一个模型类中与另一个模型类建立一个“关系”,其中“backref”参数和“db.backref”为反向引用,获取相同外键下的本模型对象的列表时,就可以通过“.[model_class_list_name]”的方式访问这些对象了;
- 一对多(多对一)关系:一对多只需要在某个模型类中定义一列外键列就行了,也可以定义一个关系变量方便访问两者之间的关系,如图:
- 多对多关系:多对多关系的建立需要两点,一是需要使用db.Table([middle_table_name], db.Column(‘[key1]‘, [column_key1_type], db.ForeignKey(‘[key1]‘), primary_key=True), db.Column(‘[key2]‘, [column_key2_type], db.ForeignKey(‘[key2]‘), primary_key=True))建立中间表(注意不是此表不是通过继承db.Model创建模型类来定义的),二是需要使用db.relationship(‘[model_class_name]‘, secondary=[middle_table_var], backref=db.backref(‘[model_class_list_name]‘))建立一个关系变量,并且指定其中间表,如图:
原文地址:https://www.cnblogs.com/guyuyun/p/9260849.html