文章目录
数据库
1、数据库的安装与配置
这节用到flask的两个扩展,使用pip安装扩展就行
pip install flask-sqlalchemy
pip install flask-mysqldb
然而,扩展只是基于数据库的一个抽象工具,就是说它只能让你的数据库更好用,但它本身并不是数据库。在使用这两个扩展之前,你还需要安装一个MySQL数据库。
按教程中的压缩包方法,反正我安装成功了,如果遇到问题,可以翻翻评论区试试。
完成安装和配置后,数据库本地服务的启动流程:
# 1.登录数据库:打开cmd,输入下面命令。成功后会显示一段Welcome的话
C:\Users\ThinkPad>mysql -u用户名 -p 密码
# 2. 创建数据库:如果创建过,可跳过
mysql> create database flask_sql_demo charset=utf8;
# 3. 启动已创建的数据库
mysql> use flask_sql_demo;
MySQL较常见的一些命令:
# 1. 显示所有表单名
mysql> show tables;
# 2. 查看一个表单的字段结构(数据字典)
mysql> desc 表单名;
# 3. 查看一个表单的内容
mysql> select * from 表单名;
# 4. 关闭数据库 --> 显示Bye
mysql> quit
# 5. 显示所有数据库
mysql> show databases;
# 6. 删除数据表
mysql> drop table 数据表名;
# 7. 删除数据库
mysql> drop database 数据库名;
2、数据库的简单使用——增删改
1. 定义数据模型
增删改的操作对象是数据表,所谓“定义数据模型”,应该就是定义表的结构。
运行代码前,并不需要在终端登录数据库,脚本中本身就会登录。在终端登录数据库可以方便查看数据库的状态。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 配置数据库的地址,url结构为'mysql://用户名:密码@IP地址/数据库名'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:写你的密码@127.0.0.1/flask_sql_demo2'
# 数据库实例
db = SQLAlchemy(app)
'''
两张表
角色(管理员,普通用户)
用户(角色id)
'''
# 数据库的模型,需要继承db.Model
class Role(db.Model):
# 定义表名
__tablename__ = 'roles'
# 定义字段 --> db.Column表示是一个字段
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
email = db.Column(db.String(32),unique=True)
password = db.Column(db.String(32))
# db.ForeignKey('roles.id'),表示是外键,表名.id
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
# -- main --
ctx = app.app_context()
ctx.push()
db.drop_all() # 删除旧表
db.create_all() # 创建新表
ctx.pop()
然后可以在终端使用mysql命令查看创建的表单
mysql> show tables;
+---------------------------+
| Tables_in_flask_sql_demo2 |
+---------------------------+
| roles |
| users |
+---------------------------+
2 rows in set (0.00 sec)
2. 增删改
Flask-SQLAlchemy的数据是有会话(Session)管理的,在增、删或修改操作后,都需要有一个提交步骤,然后变更才会在数据库中生效。
1、增加数据
ro1 = Role(name='admin')
db.session.add(ro1)
db.session.commit()
也可以批量添加提交数据
ro1 = Role(name='admin')
ro2 = Role(name='user')
db.session.add_all([ro1, ro2])
db.session.commit()
2、修改数据
ro1.name = 'other'
db.session.commit()
3、删除数据
db.session.delete(ro1)
db.session.commit()
3、 关系引用——表的关联
我们之前定义的表users
中,有一个外键role_id
,是关联到表roles
的。如果要从表users中要得到一个用户的角色的名字,就只能先得到角色的id,然后拿着这个id再到roles表中去找角色的名字,就是说需要经过两次查询。
“关系引用”的
-
作用:上述过程我只需要一次查询就可以得到用户的角色名。
-
条件:需要是“一对多”的关系;例如很多用户有相同的角色名,但一个用户只能有一个角色名;这里角色名就是“一”,用户就是“多”。
-
创建:在作为“一”的一方写关联。
创建roles表和users表之间的关联,我只需要修改类Role的定义就可以了。
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
# 在"一"的一方,写关联
# Role表增加了一个users属性
# backref='role':表示role也是User要用的属性(回关)
users = db.relationship('User', backref='role')
关联的属性不会出现在数据库的表中,我们可以通过类名.属性名
的方式来访问一个表的属性,例如
print(ro1.users)
输出的效果是这样子(下面的输出仅用于展示格式),它仅显示了类型和id,
[<User 1>, <User 2>]
如果我希望显示用户的具体信息,则需要在类的定义中加入__ref__
方法,例如在类User
中加入,
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
email = db.Column(db.String(32),unique=True)
password = db.Column(db.String(32))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
# 类的实例返回字符串
def __repr__(self) -> str:
return '<User: %s %s %s %s %s>' % (self.id, self.name, self.email, self.password, self.role_id)
则表的属性显示效果将是
[<User: 1 wang wang@123.com None 1>, <User: 2 zhang zhang@123.com None 1>]
4、查询——通过SQLAlchemy扩展
过滤器和执行器,过滤器仅对数据进行筛选,返回结果还需使用执行器。
查询users表中的所有对象
User.query.all()
查询users表中id为4的对象
# 1. 旧的,已弃用
User.query.get(4)
# 2. filter_by --> 属性=值
User.query.filter_by(id=4).first()
# 3. filter --> 类.属性==值; 更加灵活,支持比较运算符
User.query.filter(User.id==4).first()
5、其他
1. 数据模型的实现(疑惑)
感觉有些奇怪,在定义一个数据模型类时,我仅仅需要在类中定义一些变量,如__tablename__
,id
,name
,
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
后面创建数据时就可以使用这些变量名作为关键字参数传参,
ro1 = Role(name='admin')
我不知道父类db.Model做了什么可以达到这样的效果,可能我python还是学得太浅了叭。
6、Bug记录
1. 1045,”Access denied for user ‘root’@‘localhost’ “(using password: YES)
当时我在cmd可以登录数据库,可当我运行python脚本时,就报出这个错误,查了许多文章都没有解决。后来有次在终端输错了密码发现也是报这个错误,于是发现是配置数据库地址的问题,
root:mysql
中的mysql
是密码,我还以为是固定的语法就照写了。
# 错误写法
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1/flask_sql_demo2'
# 修改
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:我的密码@127.0.0.1/flask_sql_demo2'
2. RuntimeError: Working outside of application context
发现脚本中对数据库的操作就会引发改问题,一个较方便的处理方式是
ctx = app.app_context()
ctx.push()
数据库操作
ctx.pop()
参考:解决Flask中RE
参考文章中还有一种使用with的上下文管理,也是可以哒。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/114755.html