• python操作主流数据库


    为什么要学习Python操作数据库呢?我们生活在一个数据的时代,数据可以量化我们生活的方方面面,形成了海量的形形色色的数据,这些数据可以存储在关系型数据库或非关系型数据库中。要使这些数据产生价值,就必须对数据进行处理。

    而Python又是处理数据的小能手,对于常见的数据存储库。Python都有成熟的库去处理这些数据。

    MySQL

    Linux下配置MySQL环境

    # 1. 卸载安装失败的MYSQL数据库
    sudo apt-get remove mysql-server
    sudo apt-get autoremove mysql-server
    sudo apt-get remove remove mysql-common
    
    # 2. 清理MySQL相关
    dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P
    
    # 3. 安装MySQL
    // 这一步没有提示输入用户名和没密码,小坑在这就埋下了,记得之前有可以输入用户名和密码的安装包的但是给忘了?
    sudo apt-get install mysql-server
    sudo apt-get intsall mysql-client
    sudo apt-get install libmysqlclient-dev
    // 查看服务是否安装了,Shell遵循无提示即无错误
    sudo netstat -tap | grep mysql
    
    # 4. 修改配置文件使得可远程连接
    sudo vi /etc/mysql/mysql/mysql.conf.d
    将bind-address=127.0.0.1 修改为 bind-address = 0.0.0.0【主要多人操作时的限制】
    //启动服务:
    sudo /etc/init.d/mysql start
    //重启服务
    sudo /etc/init.d/mysql restart
    
    # 5. 命令式操作MySQL
    // 一定得加sudo,不然在登录的时候会提示没有权限
    $ sudo mysql -u root -p
    Enter password: 
    // 然后直接就按Enter键就行了,因为在安装mysql-server的时候没有设置用户名和密码;虽然也可以操作数据库但是操作起来非常的不方便。
    // 如果要在数据库工具如Navicate去连接的话就尴尬了会报错,以下是报错内容
    ERROR 1698 (28000): Access denied for user 'root'@'localhost'
    
    // 那么问题来了,该怎么解决呢?
    // 第一次连接不用输入密码,直接回车就可以连接
    sudo mysql -u root -p
    mysql> USE mysql;
    mysql> SELECT user, plugin FROM mysql.user;
    -- 查询结果
    +------------------+-----------------------+
    | user             | plugin                |
    +------------------+-----------------------+
    | root             | mauth_socket          |
    | mysql.session    | mysql_native_password |
    | mysql.sys        | mysql_native_password |
    | debian-sys-maint | mysql_native_password |
    | root             | mysql_native_password |
    +------------------+-----------------------+
    5 rows in set (0.00 sec)
    -- 结果发现root的plugin='auth_socket'并不是本地密码,因此需要修改它
    
    # 6. 修改MySQL的密码及验证方式
    mysql> UPDATE mysql.user SET authentication_string=PASSWORD('123'), plugin='mysql_native_password' WHERE user='root';
    # 刷新
    mysql> FLUSH PRIVILEGES;
    # 退出,再用工具连接就很简单了
    mysql> exit;
    
    # 7.注意:高版本的MySQL存在简单密码无法设置成功的安全限制,但是可以修改限制
    mysql> SET GLOBAL validate_password_policy=0;
    mysql> SET GLOBAL validate_password_mixed_case_count=0;
    mysql> SET GLOBAL validate_password_number_count=3;
    mysql> SET GLOBAL validate_password_special_char_count=0;
    mysql> SET GLOBAL validate_password_length=3;
    mysql> UPDATE mysql.user SET authentication_string=PASSWORD('123'), plugin='mysql_native_password' WHERE user='root';
    mysql> FLUSH PRIVILEGES;
    mysql> exit;
    -- 然后再登录即可。
    
    
    -- PS:如果对您有所帮助,请点个赞呗!
    
    

    MySQL语法基础

    DDL(数据定义语句)

    # 创建数据库
    CREATE DATABASE mydatabase;
    
    # 查看所有的数据库
    SHOW DATABASES;
    
    # 使用数据库
    USE mydatabase;
    
    # 创建数据表
    USE PythonDatabases;
    CREATE TABLE nets_news(
    id INT NOT NULL AUTO_INCREMENT COMMENT '自增列' PRIMARY KEY ,
    title VARCHAR(200) NOT NULL COMMENT '文章标题',
    content TEXT NOT NULL COMMENT '新闻内容',
    types VARCHAR(20) NOT NULL COMMENT '新闻类型',
    image VARCHAR(300) NULL COMMENT '新闻略缩图',
    author VARCHAR(20) NOT NULL COMMENT '文章作者',
    view_count INT DEFAULT 0 COMMENT '文章阅读量',
    create_at DATETIME NULL COMMENT '新闻时间',
    is_valid SMALLINT DEFAULT 1 COMMENT '是否显示'
    ) DEFAULT CHARSET = 'utf8';
    
    # 删除数据表
    DROP TABLE mytable;
    
    # 修改表中的字段
    # 删除字段:
    ALTER TABLE mytable  DROP i;
    # 增加字段:
    ALTER TABLE mytable ADD i INT;
    ALTER TABLE mytable ADD i INT FIRST;
    
    

    DML(数据管理语句)

    # 插入数据
    # 插入单条数据
    INSERT INTO mytable VALUE('小A', 'AA', 'male', '2019-10-29');
    # 插入多条数据
    INSERT INTO mytable VALUES('小B', 'BB', 'male', now()),
    ('小C', 'CC', 'male', now()),
    ('小D', 'DD', 'male', now());
    
    
    # 更改数据
    UPDATE mytable SET sex='famle' WHERE id=2;
    
    
    # 查询数据
    SELECT * FROM mytable WHERE id BETWEN 1 AND 2 OREDER BY id DESC LIMIT 4, 2;
    
    
    # 删除数据
    DELETE FROM mytable WHERE id=2;
    
    
    # 清空数据表
    TRUNCATE TABLE mytable;
    
    

    pymysql(原生模块API)

    在Python3.x中用于连接MySQL数据库的库;在Python2.x中连接MySQL数据库使用的是MySQLDB库。

    source env/bin/activate
    pip3 install pymysql
    
    # !pip3 install pymysql
    
    Collecting pymysql
      Downloading http://mirrors.tencentyun.com/pypi/packages/ed/39/15045ae46f2a123019aa968dfcba0396c161c20f855f11dea6796bcaae95/PyMySQL-0.9.3-py2.py3-none-any.whl (47kB)
        100% |████████████████████████████████| 51kB 763kB/s ta 0:00:011
    [?25hInstalling collected packages: pymysql
    Successfully installed pymysql-0.9.3
    

    直接连接数据库

    #!/usr/bin/env python
    # -*- encoding: utf-8 -*-
    """
    @File    :   PyMySQLSwitchDatabases.py
    @Time    :   2019/11/13 15:48
    @Author  :   Crisimple
    @Github :    https://crisimple.github.io/
    @Contact :   Crisimple@foxmail.com
    @License :   (C)Copyright 2017-2019, Micro-Circle
    @Desc    :   None
    """
    
    import pymysql
    
    class SwitchDatabase(object):
    
        def connect_databases(self):
            # 创建连接数据库的连接
            self.conn = pymysql.connect(
                host='要连接的数据库IP',
                user='数据库用户名',
                password='数据库的密码',
                database='要连接的数据库',
                charset='utf8'
            )
    
            return self.conn
    
            # # 得到一个操作MySQL的光标对象
            # 默认执行完毕返回的结果集以元组显示
            # cursor_tuple = conn.cursor()
            # # 执行完毕返回的结果以字典显示
            # cursor_dict = conn.cursor(cursor=pymysql.cursors.DictCursor)
            # # 执行sql
            # cursor_tuple.execute(sql)
            # # 关闭光标对象
            # cursor_tuple.close()
            # cursor_dict.close()
            # # 关闭数据库连接
            # conn.close()
    
        def close_databases(self):
            try:
                if self.conn:
                    return self.conn.close()
            except Exception as e:
                print("Error: %s" % e)
    
    
    if __name__ == "__main__":
        sql = """
            SELECT * FROM PythonDatabases.news
        """
        sd = SwitchDatabase()
        cursor = sd.connect_databases().cursor()
        cursor.execute(sql)
        results = cursor.fetchall()
        print(results)
        cursor.close()
        sd.close_databases()
        
    

    跳板机连数据库

    import pymysql
    from sshtunnel import SSHTunnelForwarder
    
    def write_log(message, file_name="item_count.txt"):
        mylog = open(file_name, mode='a', encoding='utf-8')
        print(message, file=mylog)
        mylog.close()
    
    
    class ConnectMysql:
        # XXX.XXX.XXX.230数据库是通过跳板机来进行连接的
        def __init__(self):
            self.db_host = "XXX.XXX.XXX.230要连接的数据库"
            self.db_port = 22
            self.db_user = "用户名"
            self.db_password = "数据库的密码"
    
            self.get_connect()
    
        # 建立连接
        def get_connect(self):
            self.server = SSHTunnelForwarder(
                    (self.db_host, self.db_port),
                    ssh_username="跳板机的用户名",
                    ssh_password="跳板机的密码",
                    remote_bind_address=('127.0.0.1', 3306)
            )
            self.server.start()
    
            self.connect = pymysql.connect(
                host="127.0.0.1",
                port=self.server.local_bind_port,
                user=self.db_user,
                password=self.db_password,
                db='btzc',
                charset='utf8mb4',
                cursorclass=pymysql.cursors.DictCursor)
    
        def close_connect(self):
            try:
                if self.connect:
                    self.connect.close()
            except Exception as e:
                print("Error %s" % e)
    
    

    查询数据

    from OperateDatabase.PyMySQLSwitchDatabases import SwitchDatabase
    
    class SelectData(object):
    
        def __init__(self):
            self.sd = SwitchDatabase()
            self.cursor = self.sd.connect_databases().cursor()
    
        def get_one(self, sql):
            self.cursor.execute(sql)
            results = self.cursor.fetchone()
            print(results)
            self.cursor.close()
            self.sd.close_databases()
    
        def get_all(self, sql):
            self.cursor.execute(sql)
            results = self.cursor.fetchall()
            print(results)
            self.cursor.close()
            self.sd.close_databases()
    
    
    if __name__ == "__main__":
        sql_ele = """
            SELECT * FROM PythonDatabases.news
        """
        sed = SelectData()
        # sed.get_one(sql_ele)
        sed.get_all(sql_ele)
    
    
    

    新增数据

    
    from OperateDatabase.PyMySQLSwitchDatabases import SwitchDatabase
    
    
    class InsertData(object):
    
        def __init__(self):
            self.sd = SwitchDatabase()
            self.cursor = self.sd.connect_databases().cursor()
    
        def insert_one(self, sql, data):
            try:
                self.cursor.execute(sql, data)
                print(sql)
                # 一定得提交数据
                self.sd.conn.commit()
            except Exception as e:
                print("Error: %s" % e)
                self.sd.conn.rollback()
            # 关闭游标
            self.cursor.close()
            self.sd.close_databases()
    
        def insert_more(self, sql, data):
            try:
                self.cursor.executemany(sql, data)
                self.sd.conn.commit()
            except Exception as e:
                print("Error: %s" % e)
                self.sd.conn.rollback()
            # 关闭游标
            self.cursor.close()
            # 关闭连接
            self.sd.close_databases()
    
    
    if __name__ == "__main__":
        sql_ele = """
            INSERT INTO PythonDatabases.news(title, content, types) VALUES(%s, %s, %s);
        """
        data_ele = (('news10', 'news10Content', 'baijia10'),
                    ('news11', 'news11Content', 'baijia11'))
        ind = InsertData()
        # ind.insert_one(sql_ele, data_ele)
        ind.insert_more(sql_ele, data_ele)
    

    更新数据

    from OperateDatabase.PyMySQLSwitchDatabases import SwitchDatabase
    
    class UpdateData(object):
    
        def __init__(self):
            self.sd = SwitchDatabase()
            self.cursor = self.sd.connect_databases().cursor()
    
        def update_one(self, sql, data):
            try:
                # sql
                self.cursor.execute(sql, data)
                self.sd.conn.commit()
            except Exception as e:
                print("Error: %s" % e)
            # 关闭游标
            self.cursor.close()
            self.sd.close_databases()
    
        def update_more(self, sql, data):
            try:
                self.cursor.executemany(sql, data)
                self.sd.conn.commit()
            except Exception as e:
                print("Error: %s" % e)
            # 关闭游标
            self.cursor.close()
            self.sd.close_databases()
    
    
    if __name__ == "__main__":
        sql_ele_one = """
            UPDATE PythonDatabases.news
            SET title = %s, content = %s, types = %s
            WHERE id = %s; 
        """
        data_ele_one = ('news20', 'news20Content', 'baijia20', '20')
    
        sql_ele_more = """
            UPDATE PythonDatabases.news
            SET title = CASE
                WHEN id = %s THEN %s
                WHEN id = %s THEN %s
                WHEN id = %s THEN %s
                END
            WHERE id in (%s, %s, %s);
        """
        data_ele_more = (7, 'news7', 8, 'news8', 9, 'news9', 7, 8, 9)
        ud = UpdateData()
        ud.update_one(sql_ele_more, data_ele_more)
    

    删除数据

    from OperateDatabase.PyMySQLSwitchDatabases import SwitchDatabase
    
    
    class DeleteData(object):
    
        def __init__(self):
            self.sd = SwitchDatabase()
            self.cursor = self.sd.connect_databases().cursor()
    
        def delete_data(self, sql, data):
            try:
                self.cursor.execute(sql, data)
                self.sd.conn.commit()
            except Exception as e:
                print("Error: %s" % e)
            # 关闭游标
            self.cursor.close()
            # 关闭连接
            self.sd.close_databases()
    
    
    if __name__ == "__main__":
        sql_ele = """
            DELETE FROM PythonDatabases.news WHERE id = %s
        """
        data_ele = (21, )
        dd = DeleteData()
        dd.delete_data(sql=sql_ele, data=data_ele)
    
    
    

    sqlalchemy(ORM框架)

    SQLAlchemy的作用是:类/对象--->SQL语句--->通过pymysql/MySQLdb模块--->提交到数据库执行

    SQLAlchemy的特性:

    优点:
        简单:ORM以最基本的形式建模数据。表的字段就是这个类的成员变量
        可读性:ORM使数据库结构文档化。比如MySQL数据库就被ORM转换为了class类
        可用性:ORM的避免了不规范、冗余、风格不统一的SQL语句,可以避免很多人为Bug,方便编码风格的统一和后期维护
        可维护性:在数据表甚至是数据库发生改变时,可以减少相应的代码修改
    
    缺点:
        性能差:自动化进行关系数据库的映射需要消耗系统性能
        多表联查效率差:在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂
        内存消耗大:越是功能强大的ORM越是消耗内存,因为一个ORM Object会带有很多成员变量和成员函数
    

    连接数据库

    #!/usr/bin/env python
    # -*- encoding: utf-8 -*-
    """
    @Desc    :   1.from SQLAlchemyConnect import News, engine
                 2.News.metadata.create_all(engine)
                 注意: sqlchemy对于Python3不友好, 链接数据库时需要用mysql+pymysql
    """
    
    from sqlalchemy import create_engine
    from pymysql import install_as_MySQLdb
    # 基类
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, DateTime, Boolean
    
    Base = declarative_base()
    
    def connect_database():
        engine = create_engine(
            'mysql+pymysql://用户名:密码@XXX.XXX.XXX.125/PythonDatabases?charset=utf8',
            max_overflow=5,
            encoding='utf8'
        )
        Base.metadata.create_all(engine)
        return engine
    
    
    class News(Base):
        __tablename__ = "news"
        id = Column(Integer, primary_key=True)
        title = Column(String(200), nullable=False)
        content = Column(String(2000), nullable=False)
        types = Column(String(10), nullable=False)
        image = Column(String(300), )
        author = Column(String(20), )
        view_count = Column(Integer)
        create_at = Column(DateTime)
        is_valid = Column(Boolean)
        # 添加配置设置编码
        __table_args__ = {
            'mysql_charset': 'utf8'
        }
    
    
    if __name__ == "__main__":
        ns = News()
    
    

    新增数据库

    from OperateDatabase.SQLAlchemyConnect import connect_database
    from sqlalchemy.orm import sessionmaker
    from OperateDatabase.SQLAlchemyConnect import News
    
    
    class InsertData(object):
        def __init__(self):
            Session = sessionmaker(bind=connect_database().engine)
            self.session = Session()
    
        def add_one(self):
            news1 = News(
                title="new1",
                content="new1content1",
                types="baijia"
            )
            news2 = News(
                title="new2",
                content="new1content2",
                types="baijia2"
            )
            news3 = News(
                title="新闻3",
                content="新闻3的Content",
                types="百家3"
            )
            news = [
                News(title="news3", content="news3Content", types="baijia3"),
                News(title="news4", content="news4Content", types="baijia4"),
                News(title="news5", content="news5Content", types="baijia5")
            ]
            # 插入单条数据
            # self.session.add(news1)
            # self.session.add(news2)
            # self.session.add(news)
    
            # 插入多条数据
            self.session.add_all(news)
            self.session.commit()
            return news
    
    if __name__ == "__main__":
        id1 = InsertData()
        print(id1.add_one())
    
    
    
    

    删除数据

    from OperateDatabase.SQLAlchemyConnect import connect_database
    from sqlalchemy.orm import sessionmaker
    from OperateDatabase.SQLAlchemyConnect import News
    
    
    class DeleteData(object):
        def __init__(self):
            Session = sessionmaker(bind=connect_database().engine)
            self.session = Session()
    
        def delete_data(self):
            """删除数据"""
            data = self.session.query(News).filter_by(title='news4')
            self.session.delete(data)
            self.session.commit()
    
    
    if __name__ == "__main__":
        dd = DeleteData()
        dd.delete_data()
    
    

    修改数据库

    from OperateDatabase.SQLAlchemyConnect import connect_database
    from sqlalchemy.orm import sessionmaker
    from OperateDatabase.SQLAlchemyConnect import News
    
    
    class UpdateData(object):
        def __init__(self):
            Session = sessionmaker(bind=connect_database().engine)
            self.session = Session()
    
        def update_data(self, pk):
            """修改数据"""
            data_lists = self.session.query(News).filter_by(id=7)
            for item in data_lists:
                item.title = "XXX"
                self.session.add(item)
            self.session.commit()
    
    
    if __name__ == "__main__":
        ud = UpdateData()
        ud.update_data(7)
    

    查询数据

    from OperateDatabase.SQLAlchemyConnect import connect_database
    from sqlalchemy.orm import sessionmaker
    from OperateDatabase.SQLAlchemyConnect import News
    
    
    class SelectData(object):
        def __init__(self):
            Session = sessionmaker(bind=connect_database().engine)
            self.session = Session()
    
        def get_one(self):
            """查询一条数据"""
            return self.session.query(News).all()
    
        def get_more(self):
            """查询多条数据"""
            return self.session.query(News).filter(News.id > 9)
    
        def order_result(self):
            """查询结果排序"""
            return self.session.query(News).order_by(News.id)
    
    
    if __name__ == "__main__":
        sd = SelectData()
        sd.get_one()
        # sd.get_more()
        # print(sd.order_result())
    

    MongoDB

    MongoDB 一个介于关系数据库和非关系数据库之间的数据库,是非关系数据库当中功能最丰富,最像关系数据库的。

    MongoDB入门

    文档

    非关系型数据库

    文档:{"foo": 3, "greeting": "Hello, MongoDB!"}--行

    区分大小写

    key唯一,不可重复

    文档可嵌套

    键值对是有序的

    集合

    集合就是一组文档

    文档类似于关系型数据库里的行,集合类似于关系型数据库里的表

    集合中的文档无需固定的结构(与关系型数据的区别)

    命名规则:

    不能是空字符串 ""
    不能包含空字符 
    不能使用syste.的前缀(系统保留的)
    建议不包含保留字 $ 用.分割不同命名空间的子集合(blog.user, blog.posts)
    

    数据库

    多个文档组成集合,多个集合组成数据库

    一个实例可以承再多个数据库

    每个数据库都有独立权限

    保留的数据库名称(admin,local,config)

    Linux下配置MongoDB环境

    安装配置

    # 傻瓜式安装mongodb
    sudo apt-get install mongodb
    
    # 压缩包式安装mongodb
    cur -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz
    tar -zxvf mongodb-linux-x86_64-3.0.6.tgz
    mv  mongodb-linux-x86_64-3.0.6/ /usr/local/mongodb
    export PATH=<mongodb-install-directory>/bin:$PATH
    
    # 卸载mongodb
    sudo apt-get --purge remove mongodb mongodb-clients mongodb-server
    
    # 查看mongodb进程是否启动
    pgrep mongo -l
    
    # mongodb 启动/重启/停止服务
    sudo service mongodb start
    sudo service mongodb restart
    sudo service mongodb stop
    

    权限划分

    # 先进入admin库
    use admin;
    
    # 查看当前有那些用户及权限
    show users;
    
    # 创建用户
    db.createUser(
        {
            user:"用户名",
            pwd:"用户密码",
            roles:[
                    {role:'userAdminAnyDatabase',db:'admin'},
                    {role:'clusterAdmin',db:'PyData'},
                  ]
        }
    );
    
    # 修改mongodb配置,开启认证模式,修改如下并重启mongodb服务
    sudo vi /etc/mongodb.conf
    # Turn on/off security.  Off is currently the default
    #noauth = true
    auth = true
    
    # 这时候输入show dbs, 会提醒进行认证操作
    # 进行用户认证
    db.auth("用户名", "用户密码")
    
    # 更新用户权限
    db.updateUser(
     "root",
            {
                roles :
                [
                      {"role" : "userAdminAnyDatabase","db" : "admin"},
                      {"role" : "dbOwner","db" : "PyData"}
                 ]
            }
    );
    
    # 删除用户
    db.dropUser("root")
    
    内置角色
        数据库用户角色
            read: 只读数据权限
            readWrite:学些数据权限
        数据库管理角色
            dbAdmin: 在当前db中执行管理操作的权限
            dbOwner: 在当前db中执行任意操作
            userADmin: 在当前db中管理user的权限
        备份和还原角色
            backup
            restore
        跨库角色
            readAnyDatabase: 在所有数据库上都有读取数据的权限
            readWriteAnyDatabase: 在所有数据库上都有读写数据的权限
            userAdminAnyDatabase: 在所有数据库上都有管理user的权限
            dbAdminAnyDatabase: 管理所有数据库的权限
        集群管理
            clusterAdmin: 管理机器的最高权限
            clusterManager: 管理和监控集群的权限
            clusterMonitor: 监控集群的权限
            hostManager: 管理Server
        超级权限
            root: 超级用户
    自定义角色
        内置角色只能控制User在DB级别上执行的操作,管理员可以创建自定义角色,控制用户在集合级别(Collection-Level)上执行的操作,即,控制User在当前DB的特定集合上执行特定的操作
    
    

    MongoDB Shell

    # -------mongodb shell---------
    # 进入数据库
    mongo
    
    # 查看有那些数据库
    show dbs;
    
    # 查看有那些集合(相当于MySQL中的table)
    show collections;
    # 或
    show tables;
    
    # 查看当前使用的那个数据
    db;
    
    # 切换到某个数据库
    use PythonDatabase;
    
    # 删除数据库
    db.dropDatabase();
    
    
    # ------集合的相关操作-------
    # 创建集合
    db.createCollection('mobileinfo');
    db.createCollection('student');
    
    # 修改集合
    db.student.renameCollection("rename_student");
    
    # 删除集合
    db.mobileinfo.drop();
    
    # 统计集合里的数据条数
    db.mobileinfo.count();
    
    # 向集合里插入数据
    db.mobileinfo.insertMany(mobile1, mobile2);
    db.mobileinfo.insert({"name": "xiaomi", "type": "xiaomi9");
    db.mobileinfo.insert({"name": "huawei", "type": "huawieP30"});
    db.mobileinfo.insert({"name": "Redmi", "type": "RedmiK20", "time": "2019"});
    db.mobileinfo.insert({"name": "Redmi6", "type": "RedmiK20", "price": 1000, "time": "2019"});
    db.mobileinfo.insert({"name": "Redmi7", "type": "RedmiK20", "price": 1200, "time": "2019"});
    db.mobileinfo.insert({"name": "Redmi8", "type": "RedmiK20", "price": 1500, "time": "2019"});
    db.mobileinfo.insert({"name": "Redmi8", "type": "RedmiK20", "price": 1500, "time": "2019"});
    db.mobileinfo.insert({"name": "Redmi9", "type": "RedmiK20", "price": 1700, "time": "2019"});
    
    # 查询数据
    # 查询集合中的所有数据
    db.mobileinfo.find();
    # 查询第一条数
    db.mobileinfo.findOne();
    # 查询第一条以后的数据
    db.mobileinfo.find().skip(1);
    # 查询前多少条数据
    db.mobileinfo.find().limit(5);
    # 对查询结果集进行统计
    db.mobileinfo.find({name: /mi/}).count();
    # 模糊匹配,匹配name中包含mi的所有数据
    db.mobileinfo.find({name: /mi/});
    # 查询name值为xiaomi的数据
    db.mobileinfo.find({name: "xiaomi"});
    # 查询price大于1200的值
    db.mobileinfo.find({price: {$gt: 1200}});
    # 查询数据price大于1700或小于1200的所有值
    db.mobileinfo.find({$or: [{price: {$lt: 1200}}, {price: {$gt: 1700}}]});
    # 查询指定列的数据(1表示显示此列的意思,也可以用true表示)
    db.mobileinfo.find({}, {name: 1, price: 1});
    # 查询以开头的所有数据
    db.mobileinfo.find({name: /^h/});
    # 查询某一列并去重
    db.mobileinfo.distinct("name");
    # 按升序排序
    db.mobileinfo.find({name: /mi/}).sort({price: 1});
    # 按降序排序
    db.mobileinfo.find({name: /mi/}).sort({price: -1});
    
    # 更新数据
    db.collection.update( criteria, objNew, upsert, multi )
    criteria : update的查询条件,类似sql update查询内where后面的
    objNew   : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
    upsert   : 如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
    multi    : mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
    db.mobileinfo.update({name: "Redmi9"}, {$inc: {price: 1501}}, false, true);
    
    # 删除数据
    db.mobileinfo.remove({name: "Redmi8"});
    
    

    远程连接

    # 修改配置如下
    sudo vi /etc/mongodb.conf
    bind_ip = 0.0.0.0(这里可以绑定多个指定的IP)
    port = 27017
    
    # 防火墙开放27017端口
    iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 27017 -j ACCEPT
    
    # 集合用户权限划分设置的用户,然后用远程工具连接即可
    
    # 或是通过命令行连接
    mongo xxx.xxx.xxx.xxx:27017/PyDatabae -u "用户名" -p "用户密码"
    
    
    

    pymongo(原生模块API)

    # pymongo 安装
    pip3 install pymongo
    
    # !pip3 install pymongo
    
    Collecting pymongo
      Downloading http://mirrors.tencentyun.com/pypi/packages/49/01/1da7d3709ea54b3b4623c32d521fb263da14822c7d9064d7fd9eeb0b492c/pymongo-3.10.1-cp36-cp36m-manylinux1_x86_64.whl (450kB)
        100% |████████████████████████████████| 460kB 3.3MB/s ta 0:00:01
    [?25hInstalling collected packages: pymongo
    Successfully installed pymongo-3.10.1
    

    连接数据库

    from pymongo import MongoClient
    
    
    class PymongoOperate(object):
        """
        连接mongodb数据库
        """
        def __init__(self):
            self.client = MongoClient(
                host="xxx.xxx.xxx.xxx",
                port=27017,
                username="用户名",
                password="用户密码"
            )
    
        """
        创建mongodb数据库
        创建集合collection
        """
        def create_db_collection(self):
            # 查询当前数据库中存在那些mongodb数据库
            # global my_db
            db_lists = self.client.list_database_names()
            print("存在数据库有:%s" % db_lists)
            # 如果数据库不存在与当前数据库列表中创建数据库,否则提示-数据库已存在
            new_mongodb = "PyData"
            if new_mongodb in db_lists:
                print("%s 已存在于 %s 中了" % (new_mongodb, db_lists))
            my_db = self.client[new_mongodb]
            new_db_lists = self.client.list_database_names()
            print("创建新数据库后,存在的数据库有:%s" % new_db_lists)
    
            # 查询当前数据库中的集合
            collection_lists = my_db.list_collection_names()
            print("已存在的集合有: %s" % collection_lists)
            # 如果数据库不存在集合则创建集合,否则提示-集合已存在
            new_collection = "py_collection"
            if new_collection in collection_lists:
                print("%s 存在于 %s" % (new_collection, collection_lists))
            my_collection = my_db[new_collection]
            new_collection_lists = my_db.list_collection_names()
            print("创建新集合后,存在的集合有:%s" % new_collection_lists)
    
        def close_connect(self):
            try:
                if self.client:
                    return self.client.close()
            except Exception as e:
                print("Error: %s" % e)
    
    
    if __name__ == "__main__":
        po = PymongoOperate()
        po.create_db_collection()
    
    

    插入数据

    from OperateDatabase.PymongoConnect import PymongoOperate
    
    class InsertData(object):
        def __init__(self):
            self.po = PymongoOperate()
            self.my_client = self.po.client
    
        def insert_data(self, db_para, collect_para, data_para):
            """
            插入一条数据
            :param db_para: 被插入的数据库
            :param collect_para: 被插入的集合
            :param data_para: 要插入的数据
            :return: 返回插入后的对象
            """
            my_db = self.my_client[db_para]
            my_collection = my_db[collect_para]
            res = my_collection.insert_one(data_para)
            print(res.inserted_id)
    
        def insert_datas(self, db_paras2=None, collect_paras2=None, data_paras2=None):
            """
            插入多条数据
            :param db_paras2: 被插入的数据库
            :param collect_paras2:被插入的集合
            :param data_paras2: 要插入的多条数据
            :return:
            """
            my_db = self.my_client[db_paras2]
            my_collection = my_db["apps"]
            res = my_collection.insert_many(data_paras2)
            print(res.inserted_ids)
    
        def id_insert_datas(self, db_para=None, collect_para=None, data_para=None):
            """
            指定id插入多条数据
            :param db_para:
            :param collect_para:
            :param data_para:
            :return:
            """
            my_db = self.my_client[db_para]
            my_collection = my_db["id_apps"]
            res = my_collection.insert_many(data_para, ordered=False)
            print(res.inserted_ids)
    
    
    if __name__ == "__main__":
        ind = InsertData()
    
        """插入一条数据"""
        db_para1 = "PyData"
        collect_para1 = "apps"
        data_para1 = {
            "company": "xiaomi", "product": "xiaomi9", "price": 2599, "release_time": "2019"
        }
        ind.insert_data(db_para=db_para1, collect_para=collect_para1,data_para=data_para1)
    
        """插入多条数据"""
        db_para2 = "PyData"
        # collect_para2 = "apps",
        data_para2 = [
            {"name": "Facebook", "alexa": "10", "url": "https://www.facebook.com"},
            {"name": "Zhihu", "alexa": "103", "url": "https://www.zhihu.com"},
            {"name": "Github", "alexa": "109", "url": "https://www.github.com"}
        ]
        # ind.insert_datas(db_paras2=db_para2, data_paras2=data_para2)
    
        """指定id插入多条数据"""
        db_para3 = "PyData"
        collect_para3 = "id_apps",
        data_para3 = [
            {"_id": 4, "name": "Facebook", "alexa": "10", "url": "https://www.facebook.com"},
            {"_id": 5, "name": "Zhihu", "alexa": "103", "url": "https://www.zhihu.com"},
            {"_id": 6, "name": "Github", "alexa": "109", "url": "https://www.github.com"}
        ]
        # ind.id_insert_datas(db_para=db_para3, data_para=data_para3)
    
    

    删除数据

    #!/usr/bin/env python
    from OperateDatabase.PymongoConnect import PymongoOperate
    
    
    class DeleteData(object):
    
        def __init__(self, db_para=None, collection_para=None):
            self.po = PymongoOperate()
            # 建立数据库连接
            self.my_client = self.po.client
            # 使用数据库
            self.my_db = self.my_client[db_para]
            # 使用集合
            self.my_collection = self.my_db[collection_para]
    
        def delete_data(self, del_data=None):
            """
            删除单条数据
            :param del_data:
            :return: {'n': 1, 'ok': 1.0} -- n为1,代表删除的数据存在
                     {'n': 1, 'ok': 1.0} -- n为1,代表删除的数据不存在
            """
            res = self.my_collection.delete_one(del_data)
            return res.raw_result
    
        def delete_datas(self, del_data=None):
            res = self.my_collection.delete_many(del_data)
            return res.deleted_count
            # return res.raw_result
    
        def delete_all(self, del_data=None):
            res = self.my_collection.delete_many({})
            return res.deleted_count
    
        def delete_collection(self):
            res = self.my_collection.drop()
            return res
    
    if __name__ == "__main__":
        dd = DeleteData(db_para="PyData", collection_para="id_apps")
    
        # 删除集合一条数据
        # print(dd.delete_data(del_data={"_id": 3}))
    
        # 删除集合多条数据
        # print(dd.delete_datas(del_data={"name": {"$regex": "^G"}}))
    
        # 删除集合所有数据
        # print(dd.delete_all())
    
        # 删除集合
        # print(dd.delete_collection())
    
    

    更新数据

    from OperateDatabase.PymongoConnect import PymongoOperate
    
    
    class UpdateData(object):
    
        def __init__(self, db_para=None, collection_para=None):
            self.po = PymongoOperate()
            self.my_client = self.po.client
            self.my_db = self.my_client[db_para]
            self.my_collection = self.my_db[collection_para]
    
        def update_data(self, old_val=None, new_val=None):
            res = self.my_collection.update_one(old_val, new_val)
            # return res.matched_count
            for i in self.my_collection.find():
                print(i)
    
        def update_datas(self, old_val=None, new_val=None):
            res = self.my_collection.update_many(old_val, new_val)
            for i in self.my_collection.find():
                print(i)
    
    
    if __name__ == "__main__":
        ud = UpdateData(db_para="PyData", collection_para="apps")
    
        # 更新集合中的一条数据
        old_val_1 = {"company": "xiaomi"}
        new_val_1 = {"$set": {"company": "xiaomi_update"}}
        # ud.update_data(old_val=old_val_1, new_val=new_val_1)
    
        # 更新集合中的多条数据
        old_val_2 = {"name": {"$regex": "^Zha"}}
        new_val_2 = {"$set": {"name": "ZhaZha********"}}
        ud.update_datas(old_val=old_val_2, new_val=new_val_2)
    
    

    查询数据

    查询单条、多条、全部数据、指定条件查询、查询后排序

    from OperateDatabase.PymongoConnect import PymongoOperate
    
    class SelectData(object):
    
        def __init__(self, db_para=None, collection_para=None):
            po = PymongoOperate()
            my_client = po.client
            self.my_db = my_client[db_para]
            self.my_collection = self.my_db[collection_para]
    
        def select_one(self):
            res = self.my_collection.find_one()
            print("查询一条数据的结果为:%s" % res)
    
        def select_all(self):
            res = self.my_collection.find()
            for i in res:
                print("查询集合中所有的结果为:%s" % i)
    
        def select_col(self, col_val=None):
            """
            查询指定字段
            :param col_val: 指定的字段
            :return:
            """
            res = self.my_collection.find({}, col_val)
            print("查询指定字段的数据:")
            for i in res:
                print("%s" % i)
    
        def select_condition(self, condition=None):
            """
            指定条件的查询
            :param condition: 查询条件
            :return:
            """
            res = self.my_collection.find(condition)
            print("指定条件的查询结果为:")
            for i in res:
                print(i)
    
        def select_sort(self, col=None, ids=None):
            """
            查询排序
            :param col: 要排序的列
            :param ids: 1:升序(默认);-1:降序
            :return:
            """
            res = self.my_collection.find().sort(col, ids)
            print("排序结果为:")
            for i in res:
                print(i)
    
    
    if __name__ == "__main__":
        sd = SelectData(db_para="PyData", collection_para="apps")
    
        # 查询一条数据
        # sd.select_one()
    
        # 查询所有数据
        # sd.select_all()
    
        # 查询指定字段的数据
        col_val_1 = {"_id": 0, "name": 1, "url": 1}
        # sd.select_col(col_val=col_val_1)
    
        # 指定条件的查询
        condition_1 = {"name": "Github"}
        # sd.select_condition(condition=condition_1)
    
        # 查询后排序
        col_1 = "alexa"
        ids_1 = -1
        sd.select_sort(col=col_1, ids=ids_1)
    
    

    MongoEngine(ORM框架)

    类比于MySQL中的SQLAlchemy ORM框架,MongoEngine是一个对象文档映射器(ODM),相当于一个基于SQL的对象关系映射器(ORM),MongoEngine提供的抽象是基于类的,创建的所有模型都是类。【MongoEngine官方文档】,英文的,Google+Baidu了好久没有发现有人翻译这个文档,突然想抽空翻译一下,立个flag。

    # !pip3 install mongoengine
    
    Collecting mongoengine
      Downloading http://mirrors.tencentyun.com/pypi/packages/ab/39/7470829474358415badc286b468d79cc2bff3caacbaf70e61eeddac58985/mongoengine-0.19.1.tar.gz (157kB)
        100% |████████████████████████████████| 163kB 1.4MB/s ta 0:00:01
    [?25hCollecting pymongo>=3.4 (from mongoengine)
      Downloading http://mirrors.tencentyun.com/pypi/packages/49/01/1da7d3709ea54b3b4623c32d521fb263da14822c7d9064d7fd9eeb0b492c/pymongo-3.10.1-cp36-cp36m-manylinux1_x86_64.whl (450kB)
        100% |████████████████████████████████| 460kB 1.5MB/s ta 0:00:01
    [?25hCollecting six>=1.10.0 (from mongoengine)
      Downloading http://mirrors.tencentyun.com/pypi/packages/65/eb/1f97cb97bfc2390a276969c6fae16075da282f5058082d4cb10c6c5c1dba/six-1.14.0-py2.py3-none-any.whl
    Building wheels for collected packages: mongoengine
      Running setup.py bdist_wheel for mongoengine ... [?25ldone
    [?25h  Stored in directory: /home/ubuntu/.cache/pip/wheels/14/c3/6a/af1febd15e2ea11580988e047c40043f26018e1407172e3465
    Successfully built mongoengine
    Installing collected packages: pymongo, six, mongoengine
    Successfully installed mongoengine-0.19.1 pymongo-3.10.1 six-1.14.0
    

    连接数据库

    from mongoengine import connect, disconnect
    from mongoengine import Document, StringField, IntField, DateTimeField
    import datetime
    
    
    class MongoConnect(object):
    
        def __init__(self):
            """
             db=None,
             alias=None,
             host=None,
             port=None,
             username=None,
             password=None,
             authentication_source=None
            """
            self.DEFAULT_CONNECTION_NAME = connect(
                # 需要连接数据库
                db="PyData",
                # 对连接的mongodb数据库起个别名,方便连接多个数据库【这是个坑】
                # alias="Al_PyData",
                # mongodb数据库服务器ip
                host="xxx.xxx.xxx.xxx",
                # mongodb数据库的端口号
                port=27017,
                # 用户名字
                username="用户名",
                # 用户密码
                password="用户密码",
                # 进行身份认证的数据库,一般都是admin
                authentication_source="admin"
            )
    
        def close_connect(self):
            try:
                if self.DEFAULT_CONNECTION_NAME:
                    return disconnect()
            except Exception as e:
                print("Error: %s" % e)
    
    
    # 定义一个文档User类,继承与Document
    class User(Document):
        name = StringField(max_length=30, required=True)
        types = IntField(default=0, required=True)
        date = DateTimeField(default=datetime.datetime.now(), required=True)
    
    
    if __name__ == "__main__":
        mc = MongoConnect()
        print("连接成功返回:%s" % mc.DEFAULT_CONNECTION_NAME)
        for i in range(10):
            User(name="%s" % i).save()
        print("成功关闭mongodb连接: %s" % disconnect())
    
    

    插入数据

    from mongoengine import Document, StringField, IntField, DateTimeField
    from datetime import datetime
    from OperateDatabase.MongoEngineConnect import MongoConnect
    
    
    class Categories(Document):
        """
        定义分类文档
        继承Document类,为普通文档
        Categories对应到mongodb数据库就是一个集合categories
        """
        name = StringField(max_length=30, required=True)
        artnum = IntField(default=0, required=True)
        date = DateTimeField(default=datetime.now(), required=True)
    
    # 插入数据类
    class InsertData(object):
        def __init__(self):
            self.my_connect = MongoConnect()
            print("成功建立mongodb连接: %s" % self.my_connect.DEFAULT_CONNECTION_NAME)
    
        def insert_data(self):
            Categories(name="J").save()
            print("成功关闭mongodb连接: %s" % self.my_connect.close_connect())
    
        def insert_datas(self):
            for i in range(5, 10):
                Categories(name="%s" % i).save()
            print("成功关闭mongodb连接: %s" % self.my_connect.close_connect())
    
    
    if __name__ == "__main__":
        ids = InsertData()
        # 插入一条数据
        # ids.insert_data()
        # 插入多条数据
        ids.insert_datas()
    
    

    删除数据

    from OperateDatabase.MongoEngineConnect import MongoConnect
    from OperateDatabase.MongoEngineConnect import User
    import mongoengine
    
    
    class DeleteData(object):
        def __init__(self):
            self.my_connect = MongoConnect()
    
        def delete_data(self):
            print("成功建立mongodb连接: %s" % self.my_connect.DEFAULT_CONNECTION_NAME)
            user1 = mongoengine.ReferenceField(name="User", reversed_delete_rule=mongoengine.CASCADE)
            print(user1)
    
    
    if __name__ == "__main__":
        dd = DeleteData()
        dd.delete_data()
    
    

    更新数据

    from OperateDatabase.MongoEngineConnect import MongoConnect
    from OperateDatabase.MongoEngineConnect import User
    
    
    class UpdateData(object):
        def __init__(self):
            self.my_connect = MongoConnect()
    
        def update_data(self):
            print("成功建立mongodb连接: %s" % self.my_connect.DEFAULT_CONNECTION_NAME)
            # user = User.objects.all()
            user1 = User.objects(name="9999xcv")
            user1.name = "dj"
            user1.update()
            print(user1.name)
            print("成功关闭连接: %s" % self.my_connect.close_connect())
    
    
    if __name__ == "__main__":
        ud = UpdateData()
        ud.update_data()
    
    

    查询数据

    from OperateDatabase.MongoEngineConnect import MongoConnect, User
    
    class SelectData(object):
        def __init__(self):
            self.my_connect = MongoConnect()
    
        def select_data(self):
            print("成功建立mongodb连接: %s" % self.my_connect.DEFAULT_CONNECTION_NAME)
            for i in User.objects.all():
                print("返回文档对象的列表: %s" % i)
                print("返回所有符合查询条件的结果的文档对象列表: %s" % i.name)
            print("成功关闭mongodb连接: %s" % self.my_connect.close_connect())
    
        # def update_select_data(self):
        #     """
        #     更新查询
        #     :return:
        #     """
        #     print("成功建立mongodb连接: %s" % self.my_connect.DEFAULT_CONNECTION_NAME)
        #     user = User(name="9999xcv")
        #     user.name = "9999xcv222333444"
        #     user.save()
        #
        #     print(user.objects)
    
    
    if __name__ == "__main__":
        # SelectData().select_data()
    
        SelectData().update_select_data()
    

    Redis

    安装个redis还这么麻烦,服务工具就是让人更方便使用的么,结果还有这么多的坑让使用者去踩,差评!总结一下自己安装redis的各种坎坷历程(不详细说了)放出下面的一步到位安装redis的教程。如果安装不成功也不要打我噢,嘿嘿,服务器种类千万种,不可避免嘛。《Redis学习文档

    Linux下配置Redis环境

    # 服务器版本,仅供参考哈
    cat /etc/issue
    Ubuntu 18.04.1 LTS 
     l
    
    # 先更新下服务器器的资源
    sudo apt-get update
    
    # 安装redis及服务
    sudo apt-get install redis
    sudo apt-get install redis-server
    
    # 修改下redis的配置文件(目的:主机上禁用了IPv6,而Ubuntu的redis-server软件包(版本5:4.0.9-1)附带了:绑定127.0.0.1 :: 1),修改如下:
    sudo /etc/redis/redis.conf
    // 注释bind地址
    #bind 127.0.0.1 ::1
    //或修改bind地址-并允许其开放访问
    bind 0.0.0.0
    # 关闭远程连接的保护
    daemonize no
    # 修改远程连接的密码
    requirepass 修改为你密码
    
    # 启动/重启/关闭redis-service服务
    sudo /etc/init.d/redis-server satrt
    sudo /etc/init.d/redis-server restart
    sudo /etc/init.d/redis-server stop
    
    # 连接redis
    $> redis-cli
    127.0.0.1:6379> auth "你设置的密码"
    127.0.0.1:6379> exit
    
    # 卸载redis及服务
    sudo apt-get purge --auto-remove redis-server
    
    # 远程连接工具
    Redis Desktop Manager
    或Intllij Idea 中的插件Redis
    
    
    # =========================redis.conf参数配置说明============================
    # Redis配置文件参数说明:
    # 1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程
    # daemonize yes
    # 2. 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
    # pidfile /var/run/redis.pid
    # 3. 指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字
    # port 6379
    # 4. 绑定的主机地址
    # bind 127.0.0.1
    # 5.当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
    # timeout 300
    # 6. 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
    # loglevel verbose
    # 7. 日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null
    # logfile stdout
    # 8. 设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id
    # databases 16
    # 9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
    # save <seconds> <changes>
    # Redis默认配置文件中提供了三个条件:
    # save 900 1
    # save 300 10
    # save 60 10000
    # 分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
    # 10. 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
    # rdbcompression yes
    # 11. 指定本地数据库文件名,默认值为dump.rdb
    # dbfilename dump.rdb
    # 12. 指定本地数据库存放目录
    # dir ./
    # 13. 设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
    # slaveof <masterip> <masterport>
    # 14. 当master服务设置了密码保护时,slav服务连接master的密码
    # masterauth <master-password>
    # 15. 设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password>命令提供密码,默认关闭
    # requirepass foobared
    # 16. 设置同一时间最大客户端连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
    # maxclients 128
    # 17. 指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区
    # maxmemory <bytes>
    # 18. 指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
    # appendonly no
    # 19. 指定更新日志文件名,默认为appendonly.aof
    # appendfilename appendonly.aof
    # 20. 指定更新日志条件,共有3个可选值:
    # no:表示等操作系统进行数据缓存同步到磁盘(快)
    # always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
    # everysec:表示每秒同步一次(折衷,默认值)
    # appendfsync everysec
    # 21. 指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析Redis的VM机制)
    # vm-enabled no
    # 22. 虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享
    # vm-swap-file /tmp/redis.swap
    # 23. 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0
    # vm-max-memory 0
    # 24. Redis swap文件分成了很多的page,一个对象可以保存在多个page上面,但一个page上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值
    # vm-page-size 32
    # 25. 设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。
    # vm-pages 134217728
    # 26. 设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4
    # vm-max-threads 4
    # 27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
    # glueoutputbuf yes
    # 28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
    # hash-max-zipmap-entries 64
    # hash-max-zipmap-value 512
    # 29. 指定是否激活重置哈希,默认为开启(后面在介绍Redis的哈希算法时具体介绍)
    # activerehashing yes
    # 30. 指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
    # include /path/to/local.conf
    
    

    Redis常用shell

    String

    # set设置值;get获取值
    127.0.0.1:6379> set animal "dog"
    OK
    127.0.0.1:6379> get animal
    "dog"
    # 设置有效期EX
    127.0.0.1:6379> set animal "chiken" EX 10
    OK
    127.0.0.1:6379> get animal
    "chiken"
    127.0.0.1:6379> get animal
    (nil)
    
    # mset设置多个键值对;mget获取多个键值对
    127.0.0.1:6379> mset key1 value1 key2 value2
    OK
    127.0.0.1:6379> mget key1 key2
    1) "value1"
    2) "value2"
    
    # append 如果键 key 已经存在并且它的值是一个字符串, APPEND 命令将把 value 追加到键 key 现有值的末尾
    # 如果 key 不存在, APPEND 就简单地将键 key 的值设为 value , 就像执行 SET key value 一样
    exists key1
    (integer) 1
    127.0.0.1:6379> append key1 append_value
    (integer) 18
    127.0.0.1:6379> get key1
    "value1append_value"
    append key3 not_exists_set_key3_and_value3
    (integer) 30
    127.0.0.1:6379> get key3
    "not_exists_set_key3_and_value3"
    
    # del删除值
    get key1
    "value1"
    127.0.0.1:6379> del key1
    (integer) 1
    127.0.0.1:6379> get key1
    (nil)
    
    # incr/decr增加或减少1
    set num 10
    OK
    127.0.0.1:6379> incr num
    (integer) 11
    127.0.0.1:6379> get num
    "11"
    127.0.0.1:6379> decr num
    (integer) 10
    127.0.0.1:6379> get num
    "10"
    127.0.0.1:6379> decr num
    (integer) 9
    127.0.0.1:6379> get num
    "9"
    
    

    List

    # LPUSH从左插入值
    127.0.0.1:6379> LPUSH lists1 value1
    (integer) 1
    127.0.0.1:6379> LPUSH lists1 value2
    (integer) 2
    127.0.0.1:6379> LRANGE lists1 0 -1
    1) "value2"
    2) "value1"
    LPUSH lists1 value3
    (integer) 3
    127.0.0.1:6379> LRANGE lists1 0 -1
    1) "value3"
    2) "value2"
    3) "value1"
    
    # RPUSH从右插入值
    127.0.0.1:6379> RPUSH lists2 value2
    (integer) 2
    127.0.0.1:6379> RPUSH lists2 value3
    (integer) 3
    127.0.0.1:6379> RPUSH lists2 value4
    (integer) 4
    127.0.0.1:6379> LRANGE lists2 0 -1
    1) "value2"
    2) "value2"
    3) "value3"
    4) "value4"
    
    # LRANGE 
    # 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
    # 负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
    
    # LTRIM截取一定长度的数据
    # 执行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三个元素,其余元素全部删除
    # 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
    # 负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
     LRANGE lists2 0 -1
    1) "value2"
    2) "value2"
    3) "value3"
    4) "value4"
    5) "value5"
    6) "value6"
    7) "value7"
    127.0.0.1:6379> LTRIM lists2 0 3
    OK
    127.0.0.1:6379> LRANGE lists2 0 -1
    1) "value2"
    2) "value2"
    3) "value3"
    4) "value4"
    
    # LPOP移除最左边的元素并返回
    127.0.0.1:6379> RPUSH course math
    (integer) 1
    127.0.0.1:6379> RPUSH course english
    (integer) 2
    127.0.0.1:6379> RPUSH course chinese
    (error) NOAUTH Authentication required.
    127.0.0.1:6379> auth Root@159357
    OK
    127.0.0.1:6379> RPUSH course chinese
    (integer) 3
    127.0.0.1:6379> LPOP course
    "math"
    127.0.0.1:6379> LRANGE course 0 -1
    1) "english"
    2) "chinese"
    
    # RPOP移除最右边的元素并返回
    127.0.0.1:6379> LRANGE course 0 -1
    1) "english"
    2) "chinese"
    127.0.0.1:6379> RPOP course
    "chinese"
    127.0.0.1:6379> LRANGE course 0 -1
    1) "english"
    
    # LPUSHX 当key存在的时候才从左边插入,不存在的时候不做任何处理,返回插入后的表的长度
    # RPUSHX 与 LPUSHX类似,但是是从右边插入的
    127.0.0.1:6379> LLEN courses
    (integer) 0
    127.0.0.1:6379> LPUSHX courses "test"
    (integer) 0
    127.0.0.1:6379> LPUSHX course "success"
    (integer) 2
    127.0.0.1:6379> LLEN course
    (integer) 2
    127.0.0.1:6379> LRANGE course 0 -1
    1) "success"
    2) "english"
    
    
    

    Set

    # ASDD添加元素
    # 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
    # 当 key 不是集合类型时,返回一个错误。
    127.0.0.1:6379> SADD set1 123
    (integer) 1
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    # 添加重复的元素
    127.0.0.1:6379> SADD set1 123
    (integer) 0
    # 添加多个元素
    127.0.0.1:6379> SADD set1 234 345 456
    (integer) 3
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "345"
    4) "456"
    
    # SREM删除元素  - 返回值为:被成功移除的元素的数量
    # 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
    # 当 key 不是集合类型,返回一个错误。
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "345"
    4) "456"
    127.0.0.1:6379> SREM set1 345
    (integer) 1
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "456"
    
    # SMEMBERS --  返回值:返回集合中的所有成员
    # 返回集合 key 中的所有成员。
    # 不存在的 key 被视为空集合。
    
    # SISMEMBER判断是否为集合的一个元素
    # 判断 member 元素是否集合 key 的成员
    # 如果 member 元素是集合的成员,返回 1 。 如果 member 元素不是集合的成员,或 key 不存在,返回 0
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "456"
    127.0.0.1:6379> SISMEMBER set1 123
    (integer) 1
    127.0.0.1:6379> SISMEMBER set1 789
    (integer) 0
    
    # SIDFF返回一个集合与其他集合的差异
    # 返回一个集合的全部成员,该集合是所有给定集合之间的差集。
    # 不存在的 key 被视为空集。
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "456"
    127.0.0.1:6379> SMEMBERS set2
    1) "123"
    2) "abc"
    3) "234"
    4) "789"
    127.0.0.1:6379> SDIFF set1 set2
    1) "456"
    127.0.0.1:6379> SDIFF set2 set1
    1) "789"
    2) "abc"
    
    # SINTER返回几个集合的交集 --  交集成员的列表。
    # 返回一个集合的全部成员,该集合是所有给定集合的交集。
    # 不存在的 key 被视为空集。
    # 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "456"
    127.0.0.1:6379> SMEMBERS set2
    1) "234"
    2) "abc"
    3) "123"
    4) "789"
    127.0.0.1:6379> SINTER set1 set2
    1) "123"
    2) "234"
    127.0.0.1:6379> SINTER set2 set1
    1) "123"
    2) "234"
    
    # SUNION返回几个集合的并集
    127.0.0.1:6379> SMEMBERS set1
    1) "123"
    2) "234"
    3) "456"
    127.0.0.1:6379> SMEMBERS set2
    1) "789"
    2) "abc"
    3) "234"
    4) "123"
    127.0.0.1:6379> SUNION set1 set2
    1) "123"
    2) "789"
    3) "abc"
    4) "234"
    5) "456"
    127.0.0.1:6379> SUNION set2 set1
    1) "123"
    2) "789"
    3) "abc"
    4) "456"
    5) "234"
    
    

    Hash

    # HSET设置散列值 
    # 将哈希表 hash 中域 field 的值设置为 value 。
    # 如果给定的哈希表并不存在, 那么一个新的哈希表将被创建并执行 HSET 操作。
    # 如果域 field 已经存在于哈希表中, 那么它的旧值将被新值 value 覆盖。
    # 返回值:当 HSET 命令在哈希表中新创建 field 域并成功为它设置值时, 命令返回 1 ; 如果域 field 已经存在于哈希表, 并且 HSET 命令成功使用新值覆盖了它的旧值, 那么命令返回 0 。
    # HGET返回哈希表中给定域的值。
    # 如果给定域不存在于哈希表中, 又或者给定的哈希表并不存在, 那么命令返回 nil
    127.0.0.1:6379> HSET hash1 google val1
    (integer) 1
    127.0.0.1:6379> HGET hash1 google
    "val1"
    
    # HMET设置多个散列值
    # HMGET获取多个散列值
    127.0.0.1:6379> HMSET website google www.google.com baidu www.baidu.com
    OK
    127.0.0.1:6379> HMGET website google baidu
    1) "www.google.com"
    2) "www.baidu.com"
    
    # HKEYS --- 返回哈希表 key 中的所有域。
    # HVALS --- 返回哈希表 key 中所有域的值。
    127.0.0.1:6379> HMGET website google baidu
    1) "www.google.com"
    2) "www.baidu.com"
    127.0.0.1:6379> HKEYS website
    1) "google"
    2) "baidu"
    127.0.0.1:6379> HVALs website
    1) "www.google.com"
    2) "www.baidu.com"
    
    # HLEN --- 返回哈希表 key 中域的数量。
    127.0.0.1:6379> HLEN website
    (integer) 2
    
    # HDEL删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
    127.0.0.1:6379> HDEL website google
    (integer) 1
    127.0.0.1:6379> HGETALL website
    1) "baidu"
    2) "www.baidu.com"
    
    # HEXISTS --- 检查给定域 field 是否存在于哈希表 hash 当中。
    # 返回值:HEXISTS 命令在给定域存在时返回 1 , 在给定域不存在时返回 0 。
    127.0.0.1:6379> HGETALL website
    1) "baidu"
    2) "www.baidu.com"
    127.0.0.1:6379> HEXISTS website baidu
    (integer) 1
    127.0.0.1:6379> HEXISTS website google
    (integer) 0
    
    
    

    redispy

    直接连接redis

    import redis
    
    
    class RedisConnect(object):
        redis_connect = redis.Redis(
            host="xxx.xxx.xxx.xxx",
            port=6379,
            password="用户名",
            db=0
        )
    
    
    if __name__ == "__main__":
        rc = RedisConnect.redis_connect
        # rc.__redis.set()
        print(rc.set())
        # print(rc.r)
    
    
    

    String

    from OperateDatabase.RedispyConnect import RedisConnect
    
    class RedisString(object):
    
        def __init__(self):
            self.rc = RedisConnect().redis_connect
    
        def set_value(self, key=None, value=None):
            """
            插入单条数据
            """
            return self.rc.set(key=key, value=value)
    
        def get_value(self, k=None):
            """
            获取单条数据
            @param k: key值
            @return:
            """
            return self.rc.get(k)
    
        def mset_values(self, **kwargs):
            """
            插入多条数据
            @param kwargs:
            @return:
            """
            return self.rc.mset(kwargs)
    
        def mget_values(self, *args):
            """
            获取多条数据
            @param args:
            @return:
            """
            return self.rc.mget(args)
    
        def append_value(self, k=None, av=None):
            """
            给k对应的value追加值
            @param k: key
            @param av: append_value
            @return: 添加后的value的总长度
            """
            return self.rc.append(k, av)
            print(self.rc.append(k, av))
    
        def del_key(self, k=None):
            """
            删除key和对应的值
            @param k:
            @return:
            """
            return self.rc.delete(k)
    
        def incr_data(self, k=None, v=None):
            """
            自增加1
            @param k:
            @param v:
            @return:
            """
            print(self.rc.set(k, v))
            print(self.rc.get(k))
            print(self.rc.incr(k))
            print(self.rc.get(k))
    
        def decr_data(self, k=None, v=None):
            """
            自减少1
            @param k:
            @param v:
            @return:
            """
            print(self.rc.set(k, v))
            print(self.rc.get(k))
            print(self.rc.decr(k))
            print(self.rc.get(k))
    
    
    if __name__ == "__main__":
        rs = RedisString()
    
        # 插入单条数据
        # rs.set_value(key="RedispyString", value="set_value2")
        # 获取单条数据
        # print(rs.get_value(k='RedispyString'))
    
        # 插入多条数据
        # rs.mset_values(RedispyStringK1="v1", RedispyStringK2="v2")
        # 获取多条数据
        # print(rs.mget_values('RedispyStringK1', 'RedispyStringK2'))
    
        # 给k对应的value追加值
        # rs.append_value(k="RedispyStringK1", av="_appendValue")
        # rs.append_value(k="RedispyStringK_None", av="_appendValue")
    
        # 删除数据
        # print(rs.del_key(k="RedispyStringK_None"))
    
        # 自增加1
        # rs.incr_data(k="RedispyStringIncrNum", v=10)
    
        # 自减少1
        # rs.decr_data(k="RedispyStringDecrNum", v=20)
    
    

    List

    from OperateDatabase.RedispyConnect import RedisConnect
    
    
    class RedisLists(object):
    
        def __init__(self):
            self.rc = RedisConnect().redis_connect
    
        def lpush_data(self, k=None, v=None):
            """
            从左边插入数据
            @param k: key
            @param v: value
            @return:
            """
            return self.rc.lpush(k, v)
    
        def rpush_data(self, k=None, v=None):
            """
            从右边插入数据
            @param k: key
            @param v: value
            @return:
            """
            return self.rc.rpush(k, v)
    
        def lrange_get(self, k=None, s=None, e=None):
            """
            获取列表的数据
            @param k: key
            @param s: 起始位置
            @param e: 结束位置
            @return: 返回列表数据
            """
            return self.rc.lrange(k, s, e)
    
        def ltrim_get(self, k=None, s=None, e=None):
            """
            截取列表
            @param k: key
            @param s: 截取的开始位置
            @param e: 截取的结束位置
            @return:
            """
            print("原列表:%s" % self.rc.lrange(k, 0, -1))
            print("截取列表:%s" % self.rc.ltrim(k, s, e))
            print("截取后的列表:%s", self.rc.lrange(k, 0, -1))
    
        def lpop_data(self, k):
            """
            从列表的最左边移除一个元素
            @param k: key
            @return: 返回移除的元素
            """
            return self.rc.lpop(k)
    
        def rpop_data(self, k):
            """
             从列表的最右边移除一个元素
            @param k: key
            @return: 返回移除的元素
            """
            return self.rc.rpop(k)
    
        def lpushx_data(self, k, v):
            """
            k存在的时候从左边插入v,k不存在的时候不做任何处理
            @param k: key
            @param v: val
            @return: 返回处理后列表的长度
            """
            return self.rc.lpushx(k, v)
    
        def rpushx_data(self, k, v):
            """
            k存在的时候从右边插入v,k不存在的时候不做任何处理
            @param k: key
            @param v: val
            @return: 返回处理后列表的长度
            """
            return self.rc.rpushx(k, v)
    
    
    if __name__ == "__main__":
        rl = RedisLists()
        # print(rl.rc)
    
        # 从左边插入数据
        # print(rl.lpush_data("list1", "v11"))
        # print(rl.lpush_data(k="list1", v="v12"))
        # print(rl.lpush_data(k="list1", v="v13"))
        # print(rl.lrange_get(k="list1", s=0, e=-1))
    
        # 从右边插入数据
        # print(rl.rpush_data(k="list1", v="v21"))
        # print(rl.rpush_data(k="list1", v="v22"))
        # print(rl.rpush_data(k="list1", v="v23"))
        # print(rl.lrange_get(k="list1", s=0, e=-1))
    
        # 截取数据
        # rl.ltrim_get(k="list1", s=0, e=3)
    
        # 从最左边移除元素
        # print(rl.lrange_get(k="list1", s=0, e=-1))
        # print(rl.lpop_data(k="list1"))
        # print(rl.lrange_get(k="list1", s=0, e=-1))
    
        # 从最右边移除元素
        # print(rl.lrange_get(k="list1", s=0, e=-1))
        # print(rl.lpop_data(k="list1"))
        # print(rl.lrange_get(k="list1", s=0, e=-1))
    
        # 不存在的key
        # print(rl.lrange_get(k="list2", s=0, e=-1))
        # print(rl.lpushx_data(k="list2", v="test_list2"))
        # 存在的key
        # print(rl.lrange_get(k="list1", s=0, e=-1))
        # print(rl.lpushx_data(k="list1", v="test_list1"))
    
    
    

    Set

    from OperateDatabase.RedispyConnect import RedisConnect
    
    
    class RedisSets(object):
    
        def __init__(self):
            self.rc = RedisConnect().redis_connect
            
        def sadd_data(self, k, *args):
            """
            添加元素
            @param k:
            @type k:
            @param v:
            @type v:
            @return:
            @rtype:
            """
            return self.rc.sadd(k, args)
        
        def smembers_get(self, k):
            """
            返回集合中的所有元素
            @param k:
            @type k:
            @return:
            @rtype:
            """
            return self.rc.smembers(k)
        
        def srem_data(self, k, v):
            """
            删除元素
            @param k:
            @type k:
            @param v:
            @type v:
            @return:
            @rtype:
            """
            return self.rc.srem(k, v)
        
        def sismember_get(self, k, v):
            """
            判读是否为集合的元素
            @param k:
            @type k:
            @param v:
            @type v:
            @return:
            @rtype:
            """
            return self.rc.sismember(k, v)
        
        def sdiff_get(self, k1, k2):
            """
            返回两个集合的差集,以位置1的集合为基准看
            @param k1:
            @type k1:
            @param k2:
            @type k2:
            @return:
            @rtype:
            """
            return self.rc.sdiff(k1, k2)
        
        def sinter_get(self, *args):
            """
            SINTER返回几个集合的交集
            @param args:
            @type args:
            @return:
            @rtype:
            """
            return self.rc.sinter(args)
        
        def sunion_get(self, *args):
            """
            SUNION返回几个集合的并集
            @param args:
            @type args:
            @return:
            @rtype:
            """
            return self.rc.sunion(args)
    
    
    if __name__ == "__main__":
        rs = RedisSets()
        # print(rs.rc)
    
        # 添加一个元素
        # print(rs.sadd_data("set1", "v2"))
        # 添加重复元素
        # print(rs.sadd_data("set1", "v2"))
        # 添加多个元素
        # print(rs.sadd_data("set2", "v3", "V4", "V5"))
        
        # 返回集合中的所有元素
        # print(rs.smembers_get("set1"))
    
        # 删除元素
        # rs.srem_data("set1", 'v1')
        # print(rs.smembers_get("set1"))
        
        # 判断是否是集合元素
        # print(rs.rc.smembers("set1"))
        # print("是集合元素:%s" % rs.sismember_get("set1", ('v2',)))
        # print("不是集合元素:%s" % rs.sismember_get("set1", ('v22', )))
        
        # 差集
        # print(rs.rc.smembers("set1"))
        # print(rs.rc.smembers("set2"))
        # print(rs.sdiff_get("set1", "set2"))
        # print(rs.sdiff_get("set2", "set1"))
        
        # 交集
        # print(rs.rc.smembers("set1"))
        # print(rs.rc.smembers("set2"))
        # print(rs.sinter_get("set1", "set2"))
        
        # 并集
        print(rs.rc.smembers("set1"))
        print(rs.rc.smembers("set2"))
        print(rs.sunion_get("set1", "set2"))
    
    
    

    Hash

    from OperateDatabase.RedispyConnect import RedisConnect
    
    class RedisHash(object):
    
        def __init__(self):
            self.rc = RedisConnect().redis_connect
            
        def hset_data(self, h, f, v):
            """
            设置值
            @param h: hash表
            @type h:
            @param f: hash表的域
            @type f:
            @param v: hash表域的值
            @type v:
            @return:
            @rtype:
            """
            return self.rc.hset(h, f, v)
        
        def hget_data(self, h, f):
            """
            返回hash表的域值
            @param h:
            @type h:
            @param f:
            @type f:
            @return:
            @rtype:
            """
            return self.rc.hget(h, f)
        
        def hmset_data(self, k, v):
            """
            设置多个域的值
            @param k:
            @type v:
            @return:
            @rtype:
            """
            return self.rc.hmset(k, v)
        
        def hmget_data(self, n, k, *args):
            """
            获取多个值
            @param k:
            @type k:
            @param args:
            @type args:
            @return:
            @rtype:
            """
            print(self.rc.hmget(n, k, args))
            
        def get_hkeys(self, n):
            """
            获取所有的key
            @param n:
            @type n:
            @return:
            @rtype:
            """
            return self.rc.hkeys(n)
        
        def get_hvals(self, n):
            """
            获取所有的值
            @param n:
            @type n:
            @return:
            @rtype:
            """
            return self.rc.hvals(n)
        
        def get_hlen(self, n):
            """
            获取hash数量
            @param n:
            @type n:
            @return:
            @rtype:
            """
            return self.rc.hlen(n)
        
        def hdel_data(self, n, f):
            """
            删除某个域及其值
            @param n:
            @type n:
            @param f:
            @type f:
            @return:
            @rtype:
            """
            return self.rc.hdel(n, f)
        
        def is_hexist(self, n, f):
            """
            判断域是否在hash表中
            @param n:
            @type n:
            @param f:
            @type f:
            @return:
            @rtype:
            """
            return self.rc.hexists(n, f)
    
    
    if __name__ == "__main__":
        rh = RedisHash()
        # print(rh.rc)
    
        # 设置值
        # print(rh.hset_data(h="company", f="google", v="www.google.com"))
        # 获取值
        # print(rh.hget_data(h="company", f="google"))
        
        # 设置多值
        # print(rh.hmset_data("company", {"k1": "v1", "k2": "v2"}))
        # 获取多个值
        # rh.hmget_data("company", ["google", "k1"], "k1")
        
        # 获取所有的key
        # print(rh.get_hkeys("company"))
    
        # 获取所有的值
        # print(rh.get_hvals("company"))
        
        # 获取hash数量
        # print(rh.get_hlen("company"))
        
        # 删除某个域及其值
        # print(rh.hdel_data("company", "google"))
        # print(rh.rc.hkeys("company"))
        
        # 判断域是否在hash表中
        print(rh.is_hexist("company", "k1"))
        print(rh.is_hexist("company", "google"))
    
    
  • 相关阅读:
    PHP为fopen,file_get_contents等函数请求web地址时增加Http头的方法
    php一些技术要点连接地址
    PHP之open_ssl
    加密解密知识 php非对称加密
    python摸爬滚打之day17----类与类之间的关系
    python摸爬滚打之day16----类的成员
    python摸爬滚打之day15----初识类
    python摸爬滚打之day14----内置函数,递归函数
    python摸爬滚打之day12----生成器, 各种生成式
    python摸爬滚打之day11----函数闭包,迭代器
  • 原文地址:https://www.cnblogs.com/secoder/p/12906416.html
Copyright © 2020-2023  润新知