美文网首页我爱编程
【笔记】《Python语言以及应用》- 文件和数据库操作

【笔记】《Python语言以及应用》- 文件和数据库操作

作者: u14e | 来源:发表于2018-04-01 01:20 被阅读28次

    一、Python操作关系型数据库


    1. SQL

    SQL语句有两种类型:

    • DDL(数据定义语言)
      • 处理用户、数据库以及表单的创建、删除、约束和权限等
    • DML(数据操作语言)
      • 处理数据插入、选择、更新和删除

    基本的SQL DDL命令:

    -- 创建数据库 CREATE DATABASE dbname
    CREATE DATABASE d
    -- 选择当前数据库 USE dbname
    USE d
    -- 删除数据库以及表单 DROP DATABASE dbname
    DROP DATABASE d
    -- 创建表 CREATE TABLE tbname(coldefs)
    CREATE TABLE t(id INT, count INT)
    -- 删除表 DROP TABLE tbname
    DROP TABLE t
    -- 删除表中所有的行 TRUNCATE TABLE tbname
    TRUNCATE TABLE t
    

    基本的SQL DML命令:

    -- 增加行 INSERT INTO tbname VALUES(...)
    INSERT INTO t VALUES(7, 40)
    -- 选择全部行和全部列 SELECT * FROM tbname
    SELECT * FROM t
    -- 选择全部行和部分列 SELECT cols FROM tbname
    SELECT id, count FROM t
    -- 选择部分行部分列 SELECT cols FROM tbname WHERE condition
    SELECT id, count FROM t WHERE count > 5 AND id = 9
    -- 修改一行的部分列 UPDATE tbname SET col=value WHERE condition
    UPDATE t SET count=3 WHERE id=5
    -- 删除部分行 DELETE FROM tbname WHERE condition
    DELETE FROM t WHERE count <= 10 OR id = 16
    

    2. DB-API

    Python访问关系型数据库的标准API

    # 连接数据库(包括用户名、密码、服务器地址...)
    connect()
    # 创建一个cursor对象来管理查询
    cursor()
    # 对数据库执行一个或多个SQL命令
    excute()
    # 等到excute之后的结果
    fetchone()、fetchmane()、fetchall()
    

    3. SQLite

    import sqlite3
    
    conn = sqlite3.connect('product.db')
    curs = conn.cursor()
    
    # 创建表
    curs.execute('''
        CREATE TABLE users (
            id        INTEGER PRIMARY KEY AUTOINCREMENT,
            username  TEXT NOT NULL,
            password  TEXT NOT NULL,
            email     TEXT
        );
    ''')
    
    # 插入数据(利用占位引用)
    sql_insert = '''
        INSERT INTO
            users (username,password,email)
        VALUES
            (?, ?, ?);
    '''
    curs.execute(sql_insert, ('admin', '123456', 'admin@qq.com'))
    
    # 更新数据
    sql_update = '''
        UPDATE
            users
        SET
            email=?
        WHERE
            id=?;
        '''
    curs.execute(sql_update, ('1@qq.com', 0))
    
    # 获取数据
    sql_select = '''
        SELECT
            id, username, password, email
        FROM
            users;
        '''
    curs.execute(sql_select)
    # 转换为python结构
    rows = curs.fetchall()
    print(rows)
    
    # 删除数据
    sql_delete = '''
        DELETE FROM
            users
        WHERE
            id=?;
        '''
    curs.execute(sql_delete, (0,))
    
    # 提交
    conn.commit()
    # 关闭连接
    conn.close()
    

    4. SQLAlchemy

    • 底层负责处理数据库连接池,执行SQL命令以及返回结果(与DB-API类似)
    • 往上是SQL表达式语言,像Python的SQL生成器
    • 高级的是对象关系映射(ORM),使用SQL表达式语言,将应用程序代码和关系型数据结构结合起来

    安装pip install sqlalchemy

    dialect + driver :// user : password @ host : port / dbname

    import sqlalchemy as sa
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker
    
    # 连接数据库
    conn = sa.create_engine('sqlite:///product.db')
    
    # 进入ORM,定义类Product,并关联它的属性和表中的列
    Base = declarative_base()
    class Product(Base):
        __tablename__ = 'product'
        identity = sa.Column('identity', sa.String, primary_key=True)
        count = sa.Column('count', sa.Integer)
        money = sa.Column('money', sa.Float)
    
        def __init__(self, identity, count, money):
            self.identity = identity
            self.count = count
            self.money = money
    
        def __repr__(self):
            return '<Product({}, {}, {})>'.format(self.id, self.count, self.money)
    
    
    # 创建数据库和表
    Base.metadata.create_all(conn)
    
    # 创建三个对象
    first = Product('a', 1, 10)
    second = Product('b', 2, 20)
    third = Product('c', 3, 30)
    
    # 创建连接到数据库的会话
    Session = sessionmaker(bind=conn)
    session = Session()
    
    # 将创建的对象写入数据库
    session.add(first)
    session.add_all([second, third])
    
    # 提交
    session.commit()
    

    5. Redis

    安装 pip install redis

    连接到redis服务器(确保电脑安装redis,并启动了redis服务器)

    import redis
    conn = redis.Redis('localhost', 6379)
    conn.keys('*')  # [...] 列出所有键
    

    字符串:

    # 设置值
    conn.set('a', 'abcdefg')    # True
    conn.set('b', 2)    # True
    conn.set('c', 1.1)  # True
    conn.setnx('a', 'a')   # False 键不存在时才设置
    conn.mset({'a1': 1, 'a2': 2, 'a3': 3})  # True 一次设置多个键值
    
    # 取值
    conn.get('c')   # b'1.1'
    conn.getset('c', 1.2)   # b'1.1' 返回旧值,同时设置新值
    conn.mget(['a1', 'a2', 'a3'])   # [b'1', b'2', b'3'] 一次取多个键的值
    
    # 获取子串
    conn.getrange('a', -2, -1)  # b'fg'
    
    # 替换子串(从指定位置开始替换,替换的子串有多长就替换多长)
    conn.setrange('a', 0, 'AA')     # 7
    conn.get('a')               # b'AAcdefg'
    
    # 删除键
    conn.delete('a')    # True
    
    # 递增递减(默认为1)
    conn.incr('b')  # 3
    conn.incr('b', 10)  # 13
    conn.decr('b')  # 12
    conn.decr('b', 10)  # 2
    conn.incrbyfloat('c')   # 2.2
    conn.incrbyfloat('c', 0.5)  # 2.7
    conn.incrbyfloat('c', -1.0) # 1.7
    

    列表(只能包含字符串):

    # 插入(第一次插入时,列表被创建)
    conn.lpush('alphabet', 'a') # 1 头部插入一项 [b'a']
    conn.lpush('alphabet', 'b', 'c') # 3 头部插入多项 [b'c', b'b', b'a']
    conn.linsert('alphabet', 'before', 'a', 'd')  # 4 某个值之前插入 [b'c', b'b', b'd', b'a']
    conn.linsert('alphabet', 'after', 'a', 'e') # 5 某个值之后插入 [b'c', b'b', b'd', b'a', b'e']
    conn.rpush('alphabet', 'g') # 6 尾部插入 [b'c', b'b', b'd', b'a', b'e', b'g']
    # 替换
    conn.lset('alphabet', 2, 'f')   # True 在索引处替换 [b'c', b'b', b'f', b'a', b'e', b'g']
    # 检索
    conn.lindex('alphabet', 2)  # b'a' 取出对应索引的值
    conn.lrange('alphabet', 0, 2)   # [b'c', b'b', b'f'] 取出指定范围的值
    conn.lrange('alphabet', 0, -1)   # [b'c', b'b', b'f', b'a', b'e', b'g'] 取出全部
    # 截取
    conn.ltrim('alphabet', 1, 4)    # True 仅保留指定范围的值 [b'b', b'f', b'a', b'e']
    

    哈希表(只能包含字符串且只有一层结构,不能嵌套)

    conn.hmset('song', {'a': 1, 'b': 2})
    conn.hset('song', 'c', 3)
    conn.hsetnx('song', 'a', 1.1)   # 键不存在时才设置
    
    conn.hget('song', 'c')  # b'3'
    conn.mget('song', 'a', 'b')     # [b'1', b'2']
    
    conn.hkeys('song')  # [b'a', b'b', b'c'] 获取所有的键
    conn.hvals('song')  # [b'1', b'2', b'3'] 获取所有的值
    conn.hlen('song')   # 3 长度
    conn.hgetall('song')    # {b'a': b'1', b'b': b'2', b'c': b'3'}
    

    集合:

    conn.sadd('weeks', 'Mon', 'Tues', 'Wed')   # 创建并添加
    
    conn.scard('weeks') # 3 长度
    
    conn.smembers('weeks')  # {b'Tues', b'Mon', b'Wed'} 获取所有值
    
    conn.srem('weeks', 'Wed')   # 删除值
    
    conn.sadd('single_weeks', 'Mon', 'Thur')
    conn.sinter('weeks', 'single_weeks')    # {b'Mon'} 返回交集
    conn.sinterstore('i_weeks', 'weeks', 'single_weeks') # 交集存于新集合i_weeks
    conn.sunion('weeks', 'single_weeks')    # 并集
    conn.sunionstore('u_weeks', 'weeks', 'single_weeks')    # 并集存于u_weeks
    conn.sdiff('weeks', 'single_weeks') # 差集
    conn.sdiffstore('d_weeks', 'weeks', 'single_weeks')    # 差集存于d_weeks
    

    有序集合:

    里面的值都是独一无二的,但是每一个值都关联对应的浮点值分数(score),可以通过值或者分数取得每一项

    用途:

    • 排行榜
    • 二级索引
    • 时间序列(把时间戳作为分数)
    # 用时间戳跟踪用户的登陆
    import time
    
    now = time.time()
    
    conn.zadd('logins', 'a', now)
    conn.zadd('logins', 'b', now+(5*60))
    conn.zadd('logins', 'c', now+(2*60*60))
    conn.zadd('logins', 'd', now+(24*60*60))
    
    conn.zrank('logins', 'c')   # c登陆的次序
    conn.zscore('logins', 'c')  # 1521453722.9854615 登陆时间
    conn.zrange('logins', 0, -1) # [b'a', b'b', b'c', b'd']
    conn.zrange('logins', 0, -1, withscores=True) 
    # [(b'a', 1521446522.9854615), (b'b', 1521446822.9854615), (b'c', 1521453722.9854615), (b'd', 1521532922.9854615)]
    

    位图:

    # 跟踪用户的登录频率
    
    # 每一天是一个单独的键,对应的用户ID设置位
    days = ['2018-03-19', '2018-03-20', '2018-03-21']
    user_1 = 1
    user_2 = 2
    user_3 = 3
    
    # 第一天的访问
    conn.setbit(days[0], user_1, 1)
    conn.setbit(days[0], user_2, 1)
    # 第二天的访问
    conn.setbit(days[1], user_1, 1)
    # 第三天的访问
    conn.setbit(days[2], user_1, 1)
    conn.setbit(days[2], user_3, 1)
    
    # 统计这三天的日访客数
    for day in days:
        conn.bitcount(day)  # 2, 1, 2
    # 查看某一天某个用户是否访问
    conn.getbit(days[1], user_2)    # 0 没访问
    # 有多少访客每天都会访问
    conn.bitop('and', 'everyday', *days)
    conn.bitcount('everyday')   # 1
    # 是否每天访问
    conn.getbit('everyday', user_3)
    # 这三天的独立访客数
    conn.bitop('or', 'allday', *days)
    conn.bitcount('allday') # 3
    

    缓存和过期:

    默认是永久的,设置5秒后过期:conn.expire(key, 5)

    二、文件和进程


    1. 文件

    file = 'oops.txt'
    BASE_DIR = os.path.dirname(os.path.abspath(__file__))
    file = os.path.join(BASE_DIR, 'test.txt')
    file_copy = os.path.join(BASE_DIR, 'test_copt.txt')
    file_rename = os.path.join(BASE_DIR, 'test_copy.txt')
    
    # 打开或创建文件
    with open(file, 'wt', encoding='utf-8') as fin:
        fin.write('hello world')
    
    # 检查文件或目录是否存在
    import os
    os.path.exists(file)  # True
    os.path.exists('.')   # True 当前目录
    os.path.exists('..')  # True  上层目录
    
    # 检查文件或目录
    os.path.isfile(file)
    os.path.isdir(file)
    
    os.path.isabs(file) # 是否是绝对路径
    
    # 复制文件
    import shutil
    shutil.copy(file, file_copy)
    # 移动文件(删除源文件)
    shutil.move(file, file_copy)
    # 重命名
    os.rename(file_copy, file_rename)
    # 删除文件
    os.remove(file_rename)
    

    2. 目录

    os.mkdir('poems') # 创建目录
    os.rmdir('poems') # 删除目录(目录必须为空)
    os.mkdir('poems/mcintyre') # 创建子目录
    # 创建文件
    with open('poems/mcintyre/main', 'wt', encoding='utf-8') as fin:
        fin.write('hello world')
    os.listdir('poems/mcintyre') # 列出目录内容
    os.chdir('poems') # 调到另一个目录
    

    glob列出匹配文件

    • * 匹配任意名称(类似于re中的.*)
    • ? 匹配一个字符
    • [abc] 匹配字符a, b, c
    • [!abc] 匹配除a, b, c以外的所有字符
    import glob
    start_b = glob.glob('b*') # 所有以b开头的文件和目录
    two_name = glob.glob('??') # 所有名称为两个字符的文件和目录
    glob.glob('[klm]*e')  # 所有以k,l或m开头并以e结尾的文件和目录
    

    3. 进程

    os.getpid() # 进程号
    os.getcwd() # 当前目录
    os.getuid()    #only Unix 用户ID
    os.getgid()    #only Unix 用户组ID
    
    import multiprocessing
    import time
    import os
    
    def whoami(what):
        print('进程 {} says: {}'.format(os.getpid(), what))
    
    def do_this(what):
        whoami(what)
    
    if __name__ == "__main__":
        whoami('我是主进程')
        for n in range(1, 5):
            p = multiprocessing.Process(target=do_this, args=('其他进程 {}'.format(n),))
            p.start()
    
    # p.terminate() # 终止进程
    

    相关文章

      网友评论

        本文标题:【笔记】《Python语言以及应用》- 文件和数据库操作

        本文链接:https://www.haomeiwen.com/subject/joxocftx.html