Python常用功能函数系列总结(四)之数据库操作

本节目录

常用函数一:redis操作

常用函数二:mongodb操作

常用函数三:数据库连接池操作

常用函数四:pandas连接数据库

常用函数五:异步连接数据库

常用函数一:redis操作

# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/06
Author: Zhang Yafei
Description: 
"""
import redis


def get_redis_conn():
    conn = redis.Redis(host='127.0.0.1', port=6379)
    return conn


def get_redis_conn_pool():
    pool = redis.ConnectionPool(host='127.0.0.1', port=6379, max_connections=1000)
    # max_connection最多创建1000个连接
    conn = redis.Redis(connection_pool=pool)
    return  conn


def redis_string_practice():
    conn = get_redis_conn_pool()
    # 添加
    conn.set('str_k', 'hello')  # 为指定key设置value
    # {'str_k':'hello'}
    conn.mset({'str_k': 'hello', 'str_k1': 'world'})  # 设置多个key/value
    # {'str_k':'hello', 'str_k1':'world'}
    conn.msetnx({'str_k': 'msetnx_hello'})  # 若当前key未设定, 则基于mapping设置key/value,结果返回True或False
    # {'str_k':'hello'}
    conn.setex('str_k2', 'str_v2', 2)  # 秒

    conn.decr('num', amount=1)
    conn.incr('num', amount=1)
    conn.incrbyfloat('num', amount='1.5')

    # 删除
    conn.delete('str_k1')

    # 修改
    conn.append('str_k', ' world')  # 为指定key添加value
    # {'str_k':'hello world'}
    conn.setrange('str_k', 5, 'world')  # 在key对应的的value指定位置上设置值
    # b'helloworld'

    # 查询
    print(conn.get('str_k'))
    print(conn.get('num'))
    print(conn.getrange('str_k', 0, 100))
    print(conn.keys())
    print(conn.strlen('str_k'))  # 长度
    print(conn.exists('str_k'))
    conn.expire('str_k1', 5)
    print(conn.get('str_k1'))

    # 添加并查询
    print(conn.getset('str_k2', 'str_v2'))
    # b'str_v2'


def redis_dict_practice():
    """
    redis dict
    redis = {
        k4:{
        'username': 'zhangyafei',
        'age': 23,
        }
    }
    """
    conn = get_redis_conn_pool()
    # 1. 创建字典
    conn.hset('k4','username','zhangyafei')
    conn.hset('k4','age',23)
    conn.hsetnx('k4','username','root')  # 若key不存在则将value赋值给key, 如果赋值成功则返回1,否则返回0
    conn.hsetnx('k4', 'hobby', 'basketball')
    conn.hmset('k4',{'username':'zhangyafei','age':23})

    # 2. 获取字典的值
    # 获取一个值
    val = conn.hget('k4', 'username')  # b'zhangyafei'
    # print(val)
    # 获取多个值
    vals = conn.mget('k4', ['username','age'])
    vals = conn.mget('k4', 'username','age')    # {b'username': b'zhangyafei', b'age': b'23'}
    # 获取所有值
    vals = conn.hgetall('k4')  # {b'username': b'zhangyafei', b'age': b'23'}
    print(vals)
    # 获取长度
    lens = conn.hlen('k4')  # 2
    str_lens = conn.hstrlen('k4', 'username')  # 10
    keys = conn.hkeys('k4')  # [b'username', b'age']
    values = conn.hvals('k4')  # [b'zhangyafei', b'23']
    judge = conn.hexists('k4', 'username')  # True
    # conn.hdel('k4', 'age', 'username')
    # print(conn.hkeys('k4')) # []

    # 计算器
    # print(conn.hget('k4', 'age'))
    # conn.hincrby('k4','age',amount=2)
    # conn.hincrbyfloat('k4','age',amount=-1.5)
    # print(conn.hget('k4', 'age'))

    # 问题:如果redis的k4对应的字典中有1000w条数据,请打印所有数据
    # 不可取:redis取到数据之后,服务器内存无法承受,爆栈
    # result = conn.hgetall('k4')
    # print(result)

    for item in conn.hscan_iter('k4'):
        print(item)


def redis_list_practice():
    """
    redis list
    redis = {
        k1: [1,2,3,]
    }
    """
    conn = get_redis_conn_pool()
    # 左插入
    conn.lpush('k1', 11)

    conn.lpush('k1', 22)
    # 右插入
    conn.rpush('k1', 33)

    # 左获取
    val = conn.lpop('k1')
    val = conn.blpop('k1', timeout=10) # 夯住
    # 右获取
    val = conn.rpop('k1')
    val = conn.brpop('k1', timeout=10) # 夯住

    conn.lpush('k1',*[12,3,1,21,21,1,212,11,1,1,1,2,2,34,5,5,5])

    def list_iter(key, count=3):
        index = 0
        while True:
            data_list = conn.lrange(key, index, index + count - 1)
            if not data_list:
                return
            index += count

            for item in data_list:
                yield item

    result = conn.lrange('k1', 0, 100)
    print(result)  # [b'22', b'11', b'33']

    for item in list_iter('k1', 3):
        print(item)


def redis_pipeline_practice():
    """
    pipeline:管道,也即事务。一次放多个值,一次执行所有管道中的操作,要么全部成功,要么全部失
    """
    conn = get_redis_conn_pool()
    pipe = conn.pipeline(transaction=True)
    pipe.multi()

    pipe.set('k2', '123')
    pipe.hset('k3', 'n1', 666)
    pipe.lpush('k4', 'laonanhai')

    pipe.execute()

def redis_set_practice():
    """
    {
        'set_k':{v1,v2,v3},
    }
    """
    conn = get_redis_conn_pool()
    # 添加
    conn.sadd('set_k', 3, 4, 5, 6)
    conn.sadd('set_k1', 3, 4, 5, 6)

    # 删除
    print(conn.spop('set_k'))
    conn.srem('set_k', 2)

    # 修改
    conn.smove('set_k', 'set_k1', 1)

    # 查询
    print(conn.smembers('set_k'))
    print(conn.smembers('set_k1'))
    print(conn.srandmember('set_k', 3))
    print(conn.scard('set_k'))
    print(conn.sismember('set_k', 2))

    print(conn.sdiff('set_k', 'set_k1'))  # 集合之差
    conn.sdiffstore('set_k_k1', 'set_k', 'set_k1')
    print(conn.smembers('set_k_k1'))

    print(conn.sinter('set_k', 'set_k1'))  # 集合交集
    conn.sinterstore('set_k_k1_inter', 'set_k', 'set_k1')
    print(conn.smembers('set_k_k1_inter'))

    print(conn.sunion('set_k', 'set_k1'))  # 集合并集
    conn.sunionstore('set_k_k1_union', 'set_k', 'set_k1')
    print(conn.smembers('set_k_k1_union'))


def redis_zset_practice():
    """
    {
        'set_k':{
            {v1: score1},
            {v2: score2},
            {v3: score3},
        },
    }
    """
    conn = get_redis_conn_pool()
    # # 添加
    # conn.zadd('zset_k', 'math', 99, 'english', 80, 'chinese', 85, 'sport', 100, 'music', 60)
    #
    # # 删除
    # conn.zrem('zset_k', 'music')
    # conn.zremrangebyrank('zset_k', 0, 0)  # 按等级大小删除, 删除等级在第min-max个值
    # conn.zremrangebyscore('zset_k', 0, 90)   # 按分数范围删除, Min < x < max之间的删除

    # 查询
    print(conn.zrange('zset_k', 0, 100))
    print(conn.zrevrange('zset_k', 0, 100))
    # score从小到大排序, 默认小值先出, 广度优先
    results = conn.zrangebyscore('zset_k', 0, 100)
    print(results)
    print(conn.zcard('zset_k'))
    print(conn.zcount('zset_k', 0, 90))
    print(conn.zrank('zset_k', 'chinese'))
    print(conn.zscore('zset_k', 'chinese'))
    print(conn.zrange('zset_k', 0, 100))


if __name__ == '__main__':
    redis_string_practice()

常用函数二:mongodb操作

import json
import pymongo
import pandas as pd


class MongoPipeline(object):
    """
    mongodb:
        save(self, data, collection):                    将数据保存到数据库
        read(self, data):                                读取数据库中指定表格
        insert(self, table, dict_data):                 插入数据
        delete(self, table, condition):                 删除指定数据
        update(self, table, condition, new_dict_data):  更新指定数据
        dbFind(self, table, condition=None):             按条件查找
        findAll(self, table):                           查找全部
        close(self):                                    关闭连接
    """

    def __init__(self, mongo_db, mongo_uri='localhost'):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def close(self):
        """
        关闭连接
        :return:
        """
        self.client.close()

    def save(self, data, collection):
        """
        将数据保存到数据库表
        :param data:
        :param collection:
        :return: None
        """
        self.collection = self.db[collection]
        try:
            if self.collection.insert(json.loads(data.T.to_json()).values()):
                print('mongodb insert {} sucess.'.format(collection))
                return
        except Exception as e:
            print('insert error:', e)
            import traceback
            traceback.print_exc(e)

    def read(self, table):
        """
        读取数据库中的数据
        :param table:
        :return: dataframe
        """
        try:
            # 连接数据库
            table = self.db[table]
            # 读取数据
            data = pd.DataFrame(list(table.find()))
            return data
        except Exception as e:
            import traceback
            traceback.print_exc(e)

    def insert(self, table, dict_data):
        """
        插入
        :param table:
        :param dict_data:
        :return: None
        """
        try:
            self.db[table].insert(dict_data)
            print("插入成功")
        except Exception as e:
            print(e)

    def update(self,table, condition, new_dict_data):
        """
        更新
        :param table:
        :param dict_data:
        :param new_dict_data:
        :return: None
        """
        try:
            self.db[table].update(condition, new_dict_data)
            print("更新成功")
        except Exception as e:
            print(e)

    def delete(self,table, condition):
        """
        删除
        :param table:
        :param dict_data:
        :return: None
        """
        try:
            self.db[table].remove(condition)
            print("删除成功")
        except Exception as e:
            print(e)

    def dbFind(self, table, condition=None):
        """
        按条件查找
        :param table:
        :param dict_data:
        :return: generator dict
        """
        data = self.db[table].find(condition)
        for item in data:
            yield item

    def findAll(self, table):
        """
        查找全部
        :param table:
        :return: generator dict
        """
        for item in self.db[table].find():
            yield item


if __name__ == '__main__':
    mongo = MongoPipeline('flask')
    # data = mongo.read('label')
    # print(data.head())
    condition = {"药品ID": 509881}
    data = mongo.dbFind('label', condition)
    print(data)
    for i in data:
        print(i)
    # mongo.findAll()

常用操作三:数据连接池操作

 

# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/06
Author: Zhang Yafei
Description: DButils连接池
"""
from DBUtils.PooledDB import PooledDB


class DBPoolHelper(object):
    def __init__(self, dbname, user=None, password=None, db_type='postgressql', host='localhost', port=5432):
        """
        # sqlite3
        # 连接数据库文件名,sqlite不支持加密,不使用用户名和密码
        import sqlite3
        config = {"datanase": "path/to/your/dbname.db"}
        pool = PooledDB(sqlite3, maxcached=50, maxconnections=1000, maxusage=1000, **config)
        # mysql
        import pymysql
        pool = PooledDB(pymysql,5,host='localhost', user='root',passwd='pwd',db='myDB',port=3306) #5为连接池里的最少连接数
        # postgressql
        import psycopg2
        POOL = PooledDB(creator=psycopg2, host="127.0.0.1", port="5342", user, password, database)
        # sqlserver
        import pymssql
        pool = PooledDB(creator=pymssql, host=host, port=port, user=user, password=password, database=database, charset="utf8")
        :param type:
        """
        if db_type == 'postgressql':
            import psycopg2
            pool = PooledDB(creator=psycopg2, host=host, port=port, user=user, password=password, database=dbname)
        elif db_type == 'mysql':
            import pymysql
            pool = PooledDB(pymysql, 5, host='localhost', user='root', passwd='pwd', db='myDB',
                            port=3306)  # 5为连接池里的最少连接数
        elif db_type == 'sqlite':
            import sqlite3
            config = {"database": dbname}
            pool = PooledDB(sqlite3, maxcached=50, maxconnections=1000, maxusage=1000, **config)
        else:
            raise Exception('请输入正确的数据库类型, db_type="postgresql" or db_type="mysql" or db_type="sqlite"')
        self.__conn = pool.connection()
        self.__cursor = self.__conn.cursor()

    def __connect_close(self):
        """关闭连接"""
        self.__cursor.close()
        self.__conn.close()

    def commit(self):
        self.__conn.commit()

    def execute_without_commit(self, sql, params=tuple()):
        self.__cursor.execute(sql, params)

    def execute(self, sql, params=tuple()):
        self.__cursor.execute(sql, params)
        self.__conn.commit()

    def execute_many(self, sql, params=tuple()):
        self.__cursor.executemany(sql, params)
        self.__conn.commit()

    def fetchone(self, sql, params=tuple()):
        self.__cursor.execute(sql, params)
        data = self.__cursor.fetchone()
        return data

    def fetchall(self, sql, params=tuple()):
        self.__cursor.execute(sql, params)
        data = self.__cursor.fetchall()
        return data

    def __del__(self):
        print("connect close ----------------")
        self.__connect_close()

 

常用操作四:pandas连接数据库

# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/06
Author: Zhang Yafei
Description: pandas连接数据库
"""
from sqlalchemy import create_engine
from pandas import read_sql


def pandas_db_helper():
    """
    'postgresql://postgres:0000@127.0.0.1:5432/xiaomuchong'
    "mysql+pymysql://root:0000@127.0.0.1:3306/srld?charset=utf8mb4"
    "sqlite: ///sqlite3.db"
    """
    engine = create_engine("sqlite:///sqlite3.db")
    conn = engine.connect()
    return conn


if __name__ == '__main__':
    conn = pandas_db_helper()
    data = read_sql("select * from articles", con=conn)
    print(data.info())

常用函数五:异步连接数据库

  • redis
# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/26
Author: Zhang Yafei
Description: 
"""
import asyncio
import aioredis


async def execute(address, password):
    print("开始执行", address)
    # 网络IO操作:创建redis连接
    redis = await aioredis.create_redis(address, password=password)
    # 网络IO操作:在redis中设置哈希值car,内部在设三个键值对,即: redis = { car:{key1:1,key2:2,key3:3}}
    await redis.hmset_dict('car', key1=1, key2=2, key3=3)
    # 网络IO操作:去redis中获取值
    result = await redis.hgetall('car', encoding='utf-8')
    print(result)
    redis.close()
    # 网络IO操作:关闭redis连接
    await redis.wait_closed()
    print("结束", address)


asyncio.run(execute('redis://127.0.0.1:6379', "0000"))
  • redis_pool
# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/26
Author: Zhang Yafei
Description: 
"""
import asyncio

import aioredis


async def execute(address, password):
    print("开始执行", address)
    # 网络IO操作:先去连接 127.0.0.1:6379,遇到IO则自动切换任务,去连接127.0.0.1:6379
    redis = await aioredis.create_redis_pool(address, password=password)
    # 网络IO操作:遇到IO会自动切换任务
    await redis.hmset_dict('car', key1=1, key2=2, key3=3)
    # 网络IO操作:遇到IO会自动切换任务
    result = await redis.hgetall('car', encoding='utf-8')
    print(result)
    redis.close()
    # 网络IO操作:遇到IO会自动切换任务
    await redis.wait_closed()
    print("结束", address)


task_list = [
    execute('redis://127.0.0.1:6379', "0000"),
    execute('redis://127.0.0.1:6379', "0000")
]

asyncio.run(asyncio.wait(task_list))
  • mysql
# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/26
Author: Zhang Yafei
Description: 
"""
import asyncio

import aiomysql


async def execute():
    # 网络IO操作:连接MySQL
    conn = await aiomysql.connect(host='127.0.0.1', port=3306, user='root', password='0000', db='mysql', )
    # 网络IO操作:创建CURSOR
    cur = await conn.cursor()
    # 网络IO操作:执行SQL
    await cur.execute("SELECT Host,User FROM user")
    # 网络IO操作:获取SQL结果
    result = await cur.fetchall()
    print(result)
    # 网络IO操作:关闭链接
    await cur.close()
    conn.close()


asyncio.run(execute())
  • mysql_pool
# -*- coding: utf-8 -*-

"""
Datetime: 2020/07/26
Author: Zhang Yafei
Description: 
"""
import asyncio

import aiomysql


async def execute(host, password):
    print("开始", host)
    # 网络IO操作:先去连接 188.176.202.180,遇到IO则自动切换任务,去连接188.176.202.181
    conn = await aiomysql.connect(host=host, port=3306, user='root', password=password, db='mysql')
    # 网络IO操作:遇到IO会自动切换任务
    cur = await conn.cursor()
    # 网络IO操作:遇到IO会自动切换任务
    await cur.execute("SELECT Host,User FROM user")
    # 网络IO操作:遇到IO会自动切换任务
    result = await cur.fetchall()
    print(result)
    # 网络IO操作:遇到IO会自动切换任务
    await cur.close()
    conn.close()
    print("结束", host)


task_list = [
    execute('127.0.0.1', "0000"),
    execute('127.0.0.1', "0000")
]
asyncio.run(asyncio.wait(task_list))

 

posted @ 2020-07-06 11:08  DreamBoy_张亚飞  阅读(743)  评论(0编辑  收藏  举报