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

一、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', '[email protected]'))

# 更新数据
sql_update = '''
    UPDATE
        users
    SET
        email=?
    WHERE
        id=?;
    '''
curs.execute(sql_update, ('[email protected]', 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 ''.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语言以及应用》- 文件和数据库操作)