每个项目都离不开数据库,所以要是打算用Flask写一个程序,我这边选择了flask-sqlalchemy
Flask-SQLAlchemy 采用数据库抽象层来操作数据库,也称为对象关系映射(Object-Relational Mapper, ORM),在用户不知不觉的情况下把高层的面向对象操作转换成低层的数据库指令,
1、下载包
pip install flask-sqlalchemy
(其实上章已经添加过了)
2、在 app/__init__.py 中实例化了 SQLAlchemy 类:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import Flask
app = Flask(__name__)
from app.controller import test
#######以下是改动部分#####
from flask_sqlalchemy import SQLAlchemy
# 配置数据库的连接
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@localhost:3306/flask'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
#让app 能找到sql.py文件
from app.controller import sql
3、定义模型
模型类可以理解为数据库中的一张表,Flask-SQLAlchemy 提供了一个基类和一系列辅助类和函数来让我们定义模型的结构。我们直接在 app 文件夹下创建一个 models.py 文件。
我这边只举个简单的例子,建一个user表
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 当前项目相关的模型文件 所有 实体类
from app import db
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, nullable=False, primary_key=True, autoincrement=True)
name = db.Column(db.String(16), nullable=False, unique=True)
password = db.Column(db.String(16), nullable=False, unique=False)
hobby = db.Column(db.String(255), nullable=False, unique=False)
# __repr__()用于显示给开发人员。
def __repr__(self):
# return '<User %r>' % self.name
return 'User(id: %d, name: %s, password: %s, hobby: %s)' % (self.id, self.name, self.password, self.hobby)
# 将db.Model 转化成json(特定方法)
def to_json(self):
dict = self.__dict__
if "_sa_instance_state" in dict:
del dict["_sa_instance_state"]
return dict
注意:
__repr__() 方法返回一个具有可读性的字符串表示模型,可以在调试和测试时使用。
db.Model 对象to json的方法比较特殊!
4、python命令行实现对数据库的操作
创建启动脚本 manage.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from app import app, db
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
这个脚本首先创建程序,然后增加了两个命令:shell 和 db,我们之后可以在命令行中直接使用。
下面我们就在命令行中操作一下数据库。
先打开cmd,然后切换到当前项目目录下
然后激活本项目的环境
首先执行:
python manage.py runserver
打开浏览器:
表面该启动脚本启动项目成功
在当前的命令行接着执行:
//创建 migrations 文件夹及相关文件
python manage.py db init
删除该目录,然后再执行一次
然后执行 :
//自动创建迁移脚本
python manage.py db migrate
//创建数据表或者升级到最新版本
python manage.py db upgrade
报错:ImportError: No module named 'MySQLdb'
参考:https://stackoverflow.com/questions/454854/no-module-named-mysqldb
执行命令:
pip install mysqlclient
又报错: error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools
参考:https://github.com/benfred/implicit/issues/76
失败!!!
那就换种方法:
通过使用Christoph Gohlke收集的
非扩展Windows二进制文件Python扩展包来解决这个障碍。下载相应的mysqlclient轮(* .whl)文件。对于Python 3.7,单击“mysqlclient-1.3.13-cp37-cp37m-win_amd64.whl”,它将下载到您的计算机。然后通过以下方式手动安装包pip
:
再次运行命令:
成功~
以后模型类有改动,比如删除或添加列,都要执行这两个命令,更新数据库表。现在在项目目录下应该自动生成了名为 dev 的数据库。
接下来执行如下命令进入 Python Shell:
python manage.py shell
创建表
使用 db.create_all() 就可以根据模型类创建表。如图:
使用 db.drop_all() 方法就可以删除所有的表,但是这种方式比较粗暴,所有的数据也一同销毁了。
查询表:
由于数据库是空的,所以就返回了这个
命令行就介绍到这了,接下来通过python代码来实现对数据库的操作
5、python代码来实现对数据库的操作
它所需的环境跟命令行一样
sql.py:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import jsonify, request
from app import app
from app.models import db, User
@app.route("/createAll", methods=['GET', ])
def createAllTables():
db.create_all()
return jsonify(msg="create successfully!")
# 插入记录、更新数据
@app.route("/add", methods=['POST', ])
def addTables():
name = request.form.get("name", None)
password = request.form.get("password", None)
hobby = request.form.get("hobby", None)
obj = User(name=name, password=password, hobby=hobby)
db.session.add(obj)
db.session.commit()
return jsonify(msg="add successfully!")
# 查询
@app.route("/selectAll", methods=['GET', ])
def selectAll():
users = User.query.all()
print(users)
array_list = []
for user in users:
array_list.append(user.to_json())
return jsonify(msg=array_list)
# 删除
@app.route("/delete", methods=['GET', ])
def delete():
user = User.query.filter_by(name='aaa').first()
if user is not None:
db.session.delete(user)
db.session.commit()
return jsonify(msg='success')
else:
return jsonify(msg='error')
注意:
“query”接口拥有丰富的方法,这里列举一些常用的:
1、“filter_by()”方法,对查询结果过滤,参数必须是键值对”key=value”
users = User.query.filter_by(name='aaa')
# WHERE name='aaa' AND hobby='wu'
users = User.query.filter_by(name='aaa', hobby='wu')
2、“filter()”,对查询结果过滤,比”filter_by()”方法更强大,参数是布尔表达式
# WHERE age<20
users = User.query.filter(User.age<20)
# WHERE name LIKE 'J%' AND age<20
users = User.query.filter(User.name.startswith('J'), User.age<20)
多个查询条件用逗号分割。
3、“first()”,取返回列表中的第一个元素,当我们只查询一条记录时非常有用
user = User.query.filter_by(name='aaa').first()
4、“order_by()”,排序
from sqlalchemy import desc
# ORDER BY name
user = User.query.order_by(User.name)
# ORDER BY age DESC, name
user = User.query.order_by(desc(User.age), User.name)
5、“limit()”和”offset()”,分页
# LIMIT 10 OFFSET 10
user = User.query.limit(10).offset(10)
6、“slice(start, stop)”,分页
# LIMIT 2 OFFSET 1
user = User.query.slice(1, 3)
从start位置开始取记录,到stop位置前结束。本质上来说,SQLAlchemy会将其翻译成LIMIT/OFFSET语句来实现,上例中的”slice(1, 3)”等同于”LIMIT 2 OFFSET 1″。
测试:
1、测试数据插入/数据更新
2、测试查询数据
3、测试删除
参考:
https://github.com/pallets/flask-sqlalchemy
http://flask-sqlalchemy.pocoo.org/2.3/