使用 Flask-SQLAlchemy 连接数据库,可以通过 Python 对象来操作数据库。
Flask-SQLAlchemy 连接数据库参考: Flask-SQLALchemy 连接数据库
连接数据库后,接下来继续介绍对数据库的基本操作。
一、数据库准备和创建表
1. 连接数据库
使用 Mysql 数据库,使用我之前创建的 admin 用户连接。
代码语言:javascript复制mysql -u admin -p
如果没有创建,就先登录 root 用户创建用户,也可以直接用 root 用户连接。用哪个用户连接无所谓,只要能正常连接就可以了。
代码语言:javascript复制grant all privileges on *.* to 'admin'@'localhost' identified by 'Mysql!123';
2. 创建一个数据库
使用我之前创建好的数据 MyDB_one ,如果没有就创建。用哪个数据库是自定义的,只要有一个数据库供使用即可。
代码语言:javascript复制create database MyDB_one charset utf8;
3. 使用 Flask-SQLAlchemy 创建数据表
创建一个 flask_alchemy_tb.py 文件,编写创建数据表的代码。
代码语言:javascript复制from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://admin:Mysql!123@127.0.0.1:3306/MyDB_one'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
class Phone(db.Model):
__tablename__ = 'Phone_tb'
pid = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
person = db.relationship('Person', backref='person')
def __repr__(self):
return 'Phone_name: {}'.format(self.name)
class Person(db.Model):
__tablename__ = 'Person_tb'
mid = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
age = db.Column(db.Integer)
phone = db.Column(db.Integer, db.ForeignKey('Phone_tb.pid'))
def __repr__(self):
return 'Person_name: {}'.format(self.name)
# db.drop_all()
db.create_all()
if __name__ == '__main__':
app.run(debug=True)
代码中连接了使用的数据库,创建了两个数据库模型类,使用 db 对象的 create_all() 方法来创建两张数据表,如果需要删除,可以使用 drop_all() 方法来删除数据表。注意删除操作要小心,删除之后表中的数据都没有了。
运行代码,就会在 MyDB_one 中创建两张数据表 Person_tb 和 Phone_tb 。
查看两张表中的字段,与代码中的字段一致。
二、常用的SQLAlchemy字段类型
创建数据表时,每个字段的数据类型是不一样的,在 SQLAlchemy 中通过 SQLAlchemy 对象 db 的字段类型来指定。
常用的字段类型有以下这些:
1. Integer: 整数,一般是32位
2. SmallInteger: 取值范围小的整数,一般是16位
3. BigInteger: 不限制长度的整数
4. Float: 浮点数
5. Numeric: 普通整数,一般是32位
6. String: 变长字符串
7. Text: 变长字符串,对较长或不限长度的字符串做了优化
8. Unicode: 变长Unicode字符串
9. Boolean: 布尔值
10. Date: 时间
11. Time: 日期和时间
三、在数据表中添加、查询、修改、删除数据
在 Flask-SQLAlchemy 中,进行添加、查询、修改、删除操作,都是由 SQLAlchemy 对象的数据库会话管理来实现的。
db 对象的数据库会话管理用 db.session 表示。
继续在上面的 .py 文件中添加代码,已经创建好了数据表,所以把创建数据表的代码注释掉。
代码语言:javascript复制# db.create_all()
app 是 Flask 的后台运行对象,创建数据库并不依赖 app 的运行,只需要使用 SQLAlchemy 对象 db 就可以了,所以把 app.run() 也注释掉。
代码语言:javascript复制# app.run(debug=True)
1. 在数据表中添加一条数据
如在 Phone_tb 中添加一条数据,先创建一个数据库模型类 Phone 的对象 phone_one,然后使用 db.session 的 add() 方法将 phone_one 添加到数据库会话中,最后执行 db.session.commit() 提交数据库会话。
代码语言:javascript复制if __name__ == '__main__':
phone_one = Phone(name='IPhone')
db.session.add(phone_one)
db.session.commit()
创建对象 phone_one 对象时通过键值对的方式指定每个字段的值,与数据库模型类中定义的字段相对应,主键可以不指定。
运行之后,会在 Phone_tb 表中添加一条 name 为 IPhone 的数据。
2. 一次在数据表中添加多条数据
可以先创建好多个数据库模型类的对象,然后使用 db.session 的 add_all() 方法将所有模型类对象以列表的方式添加到数据库会话中,最后执行 db.session.commit() 提交数据库会话。
代码语言:javascript复制 phone_two = Phone(name='Mi')
phone_three = Phone(name='NOKIA')
db.session.add_all([phone_two, phone_three])
db.session.commit()
注释掉添加一条数的代码,然后执行上面的代码,会继续在 Phone_tb 表中添加两条数据。
如果数据表中有唯一字段时,唯一字段的值不能重复,如 Person 模型类中的 name 字段,否则会报错。
如果数据表中有关系字段时,关系字段的数据必须存在,如 Person 模型类中的 phone 字段关联到 Phone 模型类中的 pid ,所以 Phone_tb 中要先有对应 pid 的数据,否则 Person_tb 中的 phone 字段为空或报错。
代码语言:javascript复制 per_one = Person(name='You', age=18, phone=1)
per_two = Person(name='Me', age=81, phone=2)
db.session.add_all([per_one, per_two])
db.session.commit()
注释掉在 Phone_tb 中添加数据的代码,在 Person_tb 中也添加两条数据。
3. 查询数据表中的数据
在 Flask-SQLAlchemy 中,查询操作是通过数据库模型类对象的 query 对象来完成的。
最基本的查询是调用 query 对象的 all() 方法返回数据表中的所有数据,也可以通过 query 对象的过滤器进行更精确的数据库查询,过滤查询后面再研究。
代码语言:javascript复制 all_person = Person.query.all()
print(all_person)
运行上面的查询代码,结果如下:
代码语言:javascript复制[Person_name: You, Person_name: Me]
这里只显示查询结果的 name 字段,是因为在定义模型类对象的时候,重写了 db.Model 的 __repr__ 方法,显示结果按 __repr__ 方法中的定义来显示。
4. 修改数据表中的数据
在 Person_tb 中,对第二条数据进行修改。
代码语言:javascript复制 me = Person.query.get(2)
print(me.phone)
me.phone = 3
db.session.commit()
me = Person.query.get(2)
print(me.phone)
先将数据查询出来,然后修改数据对象的值,再通过 db.session 数据会话将修改结果提交到数据表中,重新从数据表中查询结果,查询结果已经改变了。
运行上面的代码,第二条数据 Me 的 phone 从 2 Mi 修改为 3 NOKIA ,运行结果如下:
代码语言:javascript复制2
...
3
再到数据表中进行查询,第二条数据确实发生了变化,修改成功。
5. 删除数据表中的数据
现在将两张数据表中的所有数据都删除。
代码语言:javascript复制 all_person = Person.query.all()
all_phone = Phone.query.all()
for phone in all_phone:
db.session.delete(phone)
db.session.commit()
for person in all_person:
db.session.delete(person)
db.session.commit()
可以看到,不管是修改还是删除,都需要先从数据表中将数据查询出来。
查询出数据后,使用 db.session 数据会话的 delete() 方法来删除数据,query 对象的 all() 方法查询出来的数据是一个查询集,是可迭代的,所以可以遍历来删除。
db.session 并没有 delete_all() 的方法,如果有这个方法也是一个危险的方法,如果需要,可以自己把上面的代码封装一下,用作删除所有数据的方法。
运行上面的代码后,再到数据表中查询数据,空空如也。
在本文的所有操作中,都是通过调用各种对象的各种方法来实现的,这就是面向对象编程的魅力吧。