系统环境:Ubuntu 18.04.1 LTS
Python使用的是虚拟环境:virutalenv
Python的版本:Python 3.6.9
【简说Python WEB】数据库
SQL数据库: Oracle,MySQL,PostgreSQL等。
NOSQL数据库:redis,MongoDB等。
关系型数据库,其最大的优点:ACID
保证事务完整,确保数据一致性,可靠性。多用于管理软件,财务软件和金融领域。
非关系型数据,通常处理大量的单表数据,简单的业务逻辑场景。在性能上表现了一定的优势。由于其集群和分片特性。
如果以后有时间的话,可以单独讨论数据库这一块。这里主要以介绍使用mysql
的docker部署和通过SQLAlchemy
来操纵MySQL数据库中的表。
数据库表
roles
表
字段 | 字段类型 | 注释 |
---|---|---|
id | int | 主键,自增id |
name | varchar(20) | 角色名称 |
users
表
字段 | 字段类型 | 注释 |
---|---|---|
id | int | 主键,自增id |
username | varchar(20) | 用户名 |
role-id | int | 角色id,管理角色表 |
roles表对应多个user表的数据,是一对多的关系。
docker安装MySQL
1.docker安装
# snap install docker
CentOS
系统可以使用yum install docker
2.docker版本查询
# docker --version
Docker version 18.09.9, build 1752eb3
3.拉取MySQL官方镜像
# docker pull mysql
4.查看目前的镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql latest 9b51d9275906 2 weeks ago 547MB
5.运行mysql镜像
docker run -p 3306:3306 --name zsdmysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
上述命令的参数,有如下含义:
-
--name
指定了你要取的名字。 -
-p
对应,需要映射出来的端口。比如:3306:3306,意识表示为zsdmysql的容器里面的3306端口对应我外面这个虚拟机的3306端口。 -
-e
是mysql的命令,设置root的密码为123456 -
-d
是运行的镜像,这里是mysql
容器镜像
6.查看目前运行的容器
root@ubuntudoc:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3958ab15ea05 mysql "docker-entrypoint.s…" 8 seconds ago Up 6 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp zsdmysql
7.进入MySQL
root@ubuntudoc:~# docker exec -it zsdmysql bash
### 下述代表容器里面的情况了
root@3958ab15ea05:/# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.19 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
8.MySQL数据的一些操作:
mysql> create database zsd;
mysql> create user 'zsd'@'localhost' identified by 'zsd';
mysql> create user 'zsd'@'172.30.200.252' identified by 'zsd';
mysql> use zsd;
Database changed
mysql> grant all on zsd.* to 'zsd'@'localhost';
mysql> grant all on zsd.* to 'zsd'@'172.30.200.252';
Flask-SQLAlchemy操纵MySQL数据库
SQLAlchemy是一个关系型数据库的框架。
代码树:
.
├── app.py
├── dbconfig.py
安装Flask-SQLAlchemy
pip install Flask-SQLAlchemy
Flask-SQLAlchemy
各种数据库驱动接口,url如下:
pymysql
mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
MySQL-Python
mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
cx_Oracle
oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
Python3使用pymysql
,安装pytmysql
pip install PyMySQL
初始化
dbconfg.py
配置文件:
# coding=utf-8
HOSTNAME = '172.30.200.252'
DATABASE = 'zsd'
USERNAME = 'zsd'
PASSWORD = 'zsd'
DB_URI = 'mysql+pymysql://{}:{}@{}:3306/{}?charset=utf8'.format(
USERNAME, PASSWORD, HOSTNAME, DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = False
app.py
初始化实例
from flask_sqlalchemy import SQLAlchemy
app.config.from_object('dbconfig')
db = SQLAlchemy(app)
定义模型
app.py
的视图代码
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
def __repr__(self):
return '<User %r>' % self.username
定义关系
app.py关系代码:
class Role(db.Model):
#..
users = db.relationship('User', backref='role')
class User(db.Model):
#..
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
可以看到,User表中,定义了一个外键roles.id'
。
而Role表,定义了db.relationship
。意思可以认为,一个Role可以对应多个User实例。代表了一对多的意思
数据库的CRUD操作
创建表
(zsdpy1)$ flask shell
>>> from app import db
>>> db.create_all()
这里,就会在MySQL数据中直接创建两张表,如下:
mysql> desc zsd.users;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| username | varchar(64) | YES | UNI | NULL | |
| role_id | int | YES | MUL | NULL | |
+----------+-------------+------+-----+---------+----------------+
mysql> desc zsd.roles;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(64) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
也可以直接删除所有旧表,重置上述表,如下:
>>> db.drop_all()
>>> db.create_all()
上述操作,可是删除ORM映射的所有表和数据,必须谨慎,谨慎再谨慎!!!!
insert数据
插入一些用户的角色:
>>> from app import Role,User
>>> admin_role= Role(name='管理员')
>>> user_role= Role(name='普通用户')
>>> zsd = User(username='盛东',role=admin_role)
>>> huke =User(username='胡轲',role=user_role)
数据库是通过session交互的,如下:
>>> db.session.add(admin_role)
>>> db.session.add(user_role)
>>> db.session.add(zsd)
>>> db.session.add(huke)
亦或者,全部插入:
>>> db.session.add_all(admin_role,user_role,zsd,huke)
事务提交
>>> db.session.commit()
查看角色数据
>>> Role.query.all()
[<Role '普通用户'>, <Role '管理员'>]
update数据
>>> rs = db.session.query(User).filter_by(username='盛东').first()
>>> print(rs)
<User '盛东'>
>>> rs.username ='盛东2'
>>> db.session.commit()
查看数据库,数据修改为盛东2
mysql> select * from users;
+----+----------+---------+
| id | username | role_id |
+----+----------+---------+
| 1 | 盛东2 | 1 |
| 2 | 胡轲 | 2 |
+----+----------+---------+
delete数据
>>> rs = db.session.query(User).filter_by(username='盛东2').first()
>>> db.session.delete(rs)
>>> db.session.commit()
查询数据
>>> Role.query.all()
[<Role '普通用户'>, <Role '管理员'>]
>>> User.query.all()
[<User '胡轲'>]
>>> User.query.filter_by(username='胡轲').first()
<User '胡轲'>
错误
有如下错误:
RuntimeError: cryptography is required for sha256_password or caching_sha2_password
需要安装:
pip install cryptography