zoukankan      html  css  js  c++  java
  • 【简说Python WEB】数据库

    系统环境: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
    
  • 相关阅读:
    elasticsearch如何设计索引
    LinkedList 的实现原理
    聊聊elasticsearch7.8的模板和动态映射
    elasticsearch7.8权限控制和规划
    cloudera manager server迁移
    2020年终总结
    工作两年半的一次复盘
    聊聊数据结构和算法
    AutoMapper源码解析
    [源码解析] 并行分布式框架 Celery 之 worker 启动 (2)
  • 原文地址:https://www.cnblogs.com/zhangshengdong/p/12574337.html
Copyright © 2011-2022 走看看