【简说Python WEB】数据库

时间:2023-11-25 15:20:32

系统环境: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

上述命令的参数,有如下含义:

  1. --name指定了你要取的名字。
  2. -p对应,需要映射出来的端口。比如:3306:3306,意识表示为zsdmysql的容器里面的3306端口对应我外面这个虚拟机的3306端口。
  3. -e是mysql的命令,设置root的密码为123456
  4. -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