后端一个重要的点就是与数据库联系,例如网页的注册、登录,内容的更新等都需要与数据库建立关系。以MySQL
数据库为例,平时我们会用mysqldb(python 2)
或者pymysql(python 3)
去操作MySQL
数据库,但这种方法也是需要自己编写SQL语句的。现在我们有了ORM模型,简单来说,ORM是把数据库中的表抽象成模型,表的列名对应模型的属性,这样我们可以调用类的属性或方法去获得数据库中的数据。例如假设MySQL
数据库中有一张表名为table1
,使用SELECT * FROM table1 WHERE id=1
获取id
为1
的数据,如果将表table1
映射成ORM模型Table
,那么可以直接使用Table.query.filter(id=1)
,这样操作简单了很多,也很利于理解。
SQLAlchemy
就是一个这样的ORM,我们可以直接安装flask_sqlalchemy
来使用。在这之前我们先在MySQL
中手动建立一个数据库harp
,在建立的时候把charset
设置为utf8
,避免存入中文时变成乱码,然后在配置文件config.py
中填写好数据库的连接信息:
HOST = "127.0.0.1"
PORT = "3306"
DB = "harp"
USER = "root"
PASS = "Your Password"
CHARSET = "utf8"
DB_URI = "mysql+pymysql://{}:{}@{}:{}/{}?charset={}".format(USER, PASS, HOST, PORT, DB, CHARSET)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLAlchemy
依赖mysqldb
或者pymysql
去连接数据库和执行SQL语句,因为我们用的是python 3
,所以需要在配置信息中指明使用pymysql
,如果是python 2
可以省略,默认是使用mysqldb
。
建立好了数据库,我们开始建表,首先建立一张用户表,我们设想它应该有id(作为主键)、用户名、密码、注册时间这些基本的字段,有了ORM,我们就不用再写SQL去建表了,在项目的主py文件中添加以下代码:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
import config
app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)
class Users(db.Model):
__tablename__ = 'users_info'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(32), nullable=False)
password = db.Column(db.String(100), nullable=False)
register_time = db.Column(db.DateTime, nullable=False, default=datetime.now())
db.create_all()
解读一下这段代码,导入SQLAlchemy
和含有数据库连接信息的config
,实例化一个SQLAlchemy
对象名为db
,其传入的参数为Flask
实例app
。接下来定义了一个User
类,这个类就是ORM中的模型,也就是数据库中的表映射的模型,它需要继承自db.Model
,__tablename__
这个属性就是建表后,数据库生成的表名;然后使用db.Column
来实例化id/username/password/register_time
这几个列,db.Column
的参数描述列的类型、主键等信息,如db.Integer/db.String(32)/db.DateTime
分别代表整形、字符串(最大长度)、时间,primary_key=True
说明该字段为主键,autoincrement=True
代表自增长,nullable
决定是否可为空,default
代表默认值。最后用db.create_all()
来实现创建。我们暂时不用理解为何SQLAlchemy
需要传入Flask
实例作为参数,为何模型要继承自db.Model
,重要的是可以先把想要的表建立起来。
进入数据库,输入desc user_info;
,我们发现表已经建立好了,其结构图如下:
但它现在还是空的,我们来试着插入一条语句,将视图函数修改为:
@app.route('/')
def index():
user = Users(username='Harp', password='123456')
db.session.add(user)
db.session.commit()
return render_template('home.html')
代码实例化一个Users
的对象user
,传入username
和password
,使用db.session.add(user)
将其加入到数据库的session
(可以理解为事务)中,然后使用db.session.commit()
提交。我们运行程序,然后用浏览器访问,浏览器正常显示了结果,这时再看一眼数据库,发现这条数据已经写入到了数据库:
查询、修改数据也同样很简单:
@app.route('/')
def index():
user = Users.query.filter(Users.id == 1).first() #查找
print(user.username)
user.username = 'Harp1207' #修改
db.session.commit() #修改后需提交
print(user.username)
return render_template('home.html')
思考问题:
1.为何要把模型的操作语句放在视图函数中?(搜索上下文这个概念)
2.数据查找,我们用的是Model.query
,其实还可以用db.session.query
,两者有何区别?filter和filter_by又有何区别?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。