使用sqlalchemy只需要:
User.query.all()
二者产生的结果完全相同,所以,选择Flask-SQLAlchemy没商量。
废话不多说,立即开始。
首先,进入上一篇已经建立好的ahoh文件夹,然后激活Python虚拟环境:
~$ cd ahoh
~/ahoh$ . venv/bin/activate
在使用Flask-SQLAlchemy之前,需要先安装对应的包,以及Mysql驱动程序pymysql:
(venv)~/ahoh$ pip install pymysql
(venv)~/ahoh$ pip install flask-sqlalchemy
安装完成后,在~/ahoh/app.py文件中引入Flask-SQLAlchemy对应的类:
from flask_sqlalchemy import SQLAlchemy
然后在 app=Flask(__name__)语句后面添加配置对应的参数,并创建SQLAlchemy对象:
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:123456@localhost/ahoh?charset=utf8',
SQLALCHEMY_TRACK_MODIFICATIONS=True
)
db= SQLAlchemy(app)
SQLALCHEMY_DATABASE_URI变量的配置,就是为了向SQLAlchemy指明你使用的数据库类型、驱动、数据库用户名、密码、IP和数据库名,具体如下图:
然后,不要忘了,在Mysql中创建对应的数据库,这里使用的是ahoh,创建数据库命令如下:
create database ahoh;
到这里,Flask-SQLAlchemy插件的配置工作已经完成了,但是,现在还不能测试。
既然是对象关系映射(ORM)框架,必然还要提供对象,然后才能映射到关系表。
所谓SQLAlchemy对象,无非就是一个特殊的类,这里就直接在app.py文件的末尾,追加User类:
class User(db.Model):
tablename = 't_users' # 对应的数据库表名
id = db.Column(db.Integer, primary_key=True, autoincrement=True) # 自增主键
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True)
password = db.Column(db.String(127), nullable=False)
这个类中的每一个属性,都对应数据库中表的一列,应该还是比较容易理解的,db.Integer和db.String是最常用的两个类型,SQLAlchemy还有很多其他类型的数据,后面后逐步扩展我们的代码。
为了保证大家都跟的上,下面贴出app.py的代码:
~/ahoh/app.py
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(name)
app.config.from_mapping(
SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:123456@localhost/ahoh?charset=utf8',
SQLALCHEMY_TRACK_MODIFICATIONS=True
)
db = SQLAlchemy(app)
@app.route('/')
def index():
return '你好, Flask'
... ... # 代码过长,此处省略其他视图函数
class User(db.Model):
tablename = 't_users'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True)
password = db.Column(db.String(127), nullable=False)
OK,到了这里,所有的sqlalchemy工作就算做完了,下面开始测试工作。
下面就用Flask Shell完成数据库中表的创建工作,测试代码正确性。
首先使用Ctrl+C停下正在运行的Flask服务,然后在命令行中输入:
(venv)~/ahoh$ flask shell # 启动Flask Shell
Python 3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0] on linux
App: app [production]
Instance: /home/wei/ahoh/instance
# 出现命令提示符表示成功启动
Flask Shell 和Python可交互编程环境差不多,我们不做深究,直接开始。
在Shell中输入以下代码:
from app import db # 引入db变量
db.create_all() # 创建所有的表
以上指令,就会创建所有继承了db.Model的类对应的表了,如果在输入db.create_all()后没有任何输出(没有报错信息),大概率就是成功了。
然后,新开一个终端,进入Mysql查看ahoh数据库中是否真的创建了表:
mysql> use ahoh;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+----------------+
| Tables_in_ahoh |
+----------------+
| t_users |
+----------------+
1 row in set (0.00 sec)
mysql>
还可以使用 DESC指令查看表的结构:
mysql> desc t_users;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(80) | NO | UNI | NULL | |
| email | varchar(120) | YES | UNI | NULL | |
| password | varchar(127) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql>
建表工作这里就完成了,下面测试数据表的增删改查。
回到Flask Shell,输入以下指令,向t_users表中插入数据:
from app import User # 引入User类
u = User(username='xiaoming',email='123@123.com',password='123456') # 创建User实例
db.session.add(u) # 向数据库添加新数据
db.session.commit() # 提交
如果执行以上指令之后,没有报错信息,就厉害大发了。
赶快回到Mysql查看一下t_users表里面到底有没有数据,使用以下指令:
mysql> select * from t_users; # 查询表中所有数据
+----+----------+-------------+----------+
| id | username | email | password |
+----+----------+-------------+----------+
| 1 | xiaoming | 123@123.com | 123456 |
+----+----------+-------------+----------+
1 row in set (0.00 sec)
输出和我一样就证明没有问题了!
提醒:密码明文存储是非常愚蠢的行为,这里仅供展示使用,后面会使用加密手段
这也是为什么密码列预留空间很大的原因,你发现了吗
只有一条数据肯定不像话,多加几条:
u1 = User(username='aaa',password='bbb',email="123@qwe.com")
u2 = User(username='eee',password='bbb',email="qwe@qwe.com")
db.session.add(u1)
db.session.add(u2)
db.session.commit()
然后测试删、改功能:
删除测试
u = User.query.filter_by(username='aaa').first() # 查询
u.username
'aaa'
db.session.delete(u) # 删除
db.session.commit()
修改测试
u = User.query.filter_by(username='xiaoming').first()
u.username
'xiaoming'
u.username='老天爷'
db.session.add(u)
db.session.commit()
现在数据库和Flask-SQLAlchemy插件都配置好了,新问题又来了。
我现在对数据表不满意,因为没有年龄age字段,而且我希望最终建立的数据库有很多表,和现在差距肯定非常大。
所以我需要不断的修改db.Model的子类,如何在每次修改对象类后,将改动同步到数据库呢?
这就需要Flask-Migrate插件了,首先,老规矩,安装插件:
(venv) ~/ahoh$ pip install flask-migrate
接下来就是配置Flask-Migrate插件,非常简单,先在app.py文件头部导入:
from flask_migrate import Migrate
然后在db=SQLAlchemy(app)后创建migrate实例:
migrate = Migrate(app, db)
这样就配置完成了。
Flask-Migrate的使用也很方便,包括三条命令
首先就是初始化命令:flask db init
在首次安装Flask-Migrate插件后,需要执行一次,后面就不需要了。
我们先初始化:
(venv) ~/ahoh$ flask db init
Creating directory /home/wei/ahoh/migrations ... done
Creating directory /home/wei/ahoh/migrations/versions ... done
Generating /home/wei/ahoh/migrations/script.py.mako ... done
Generating /home/wei/ahoh/migrations/env.py ... done
Generating /home/wei/ahoh/migrations/alembic.ini ... done
Generating /home/wei/ahoh/migrations/README ... done
Please edit configuration/connection/logging settings in '/home/wei/ahoh/migrations/alembic.ini' before
proceeding.
一、Python所有方向的学习路线
Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、学习软件
工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。
三、入门学习视频
我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。