为何要学习Python操做数据库呢?咱们生活在一个数据的时代,数据能够量化咱们生活的方方面面,造成了海量的形形色色的数据,这些数据能够存储在关系型数据库或非关系型数据库中。要使这些数据产生价值,就必须对数据进行处理。html
而Python又是处理数据的小能手,对于常见的数据存储库。Python都有成熟的库去处理这些数据。python
# 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:若是对您有所帮助,请点个赞呗!
# 建立数据库 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;
# 插入数据 # 插入单条数据 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;
在Python3.x中用于链接MySQL数据库的库;在Python2.x中链接MySQL数据库使用的是MySQLDB库。mysql
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) [K 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的做用是:类/对象--->SQL语句--->经过pymysql/MySQLdb模块--->提交到数据库执行linux
SQLAlchemy的特性:git
优势: 简单: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 一个介于关系数据库和非关系数据库之间的数据库,是非关系数据库当中功能最丰富,最像关系数据库的。github
非关系型数据库web
文档:{"foo": 3, "greeting": "Hello, MongoDB!"}--行redis
区分大小写算法
key惟一,不可重复sql
文档可嵌套
键值对是有序的
集合就是一组文档
文档相似于关系型数据库里的行,集合相似于关系型数据库里的表
集合中的文档无需固定的结构(与关系型数据的区别)
命名规则:
不能是空字符串 "" 不能包含空字符 \0 不能使用syste.的前缀(系统保留的) 建议不包含保留字 $ 用.分割不一样命名空间的子集合(blog.user, blog.posts)
多个文档组成集合,多个集合组成数据库
一个实例能够承再多个数据库
每一个数据库都有独立权限
保留的数据库名称(admin,local,config)
# 傻瓜式安装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--------- # 进入数据库 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 安装 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) [K 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)
类比于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) [K 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) [K 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学习文档》
# 服务器版本,仅供参考哈 cat /etc/issue Ubuntu 18.04.1 LTS \n \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
# 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"
# 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"
# 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"
# 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
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)
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)
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"))
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"))
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"))