Python操作三大数据库
在我们用Python语言开发软件时会经常用到三大数据库去存储数据:Mysql,MongoDB,Redis;
作为复习今天重新写一遍方便日后复习Python操作各大数据库的方法用法;
Python操作Mysql
DDL(数据库定义语句)
create table/database
alter table/database
drop table/database
DML(数据管理语句)
insert 新增
delete 删除
update 修改
select 查询
在python2中,连接Mysql的库大多是使用MySQLdb,但是此库官方并不支持Python3,所以我们用PyMySQL
直接 pip install pymysql 即可
import pymysql
db = pymysql.connect(host='localhost',port=3306,user='root',password='12345') # 连接mysql,声明一个连接对象db
cursor = db.cursor() # 获取操作游标
cursor.execute('select version()')# 查询数据库版本,返回的是查询到的数量
# version = cursor.execute('select version()') # 使用游标执行sql语句
data = cursor.fetchone() # 获得第一条数据,也就得到了版本号
print(data)
----------------------------------结果
('5.7.17-log',)
查询数据库:
cursor.execute('show databases')
databases = cursor.fetchall() # fetchall()方法获取所有结果,元组的形式
print(databases)
----------------------------
(('information_schema',), ('dailyfresh',), ('hive',), ('ihome',), ('images360',), ('lagou',), ('movie',), ('mxonline',), ('mysql',), ('news',), ('performance_schema',), ('solar',), ('sougou_data_result',), ('spiders',), ('student',), ('sys',), ('testdjango',))
创建数据库:
cursor.execute('create database test_Mysql default character set utf8')# 创建数据库,使用默认utf8编码
创建表:
在创建完数据库test_Mysql后,我们想要使用该数据库只需要在链接时多制定一个db参数即可
import pymysql
db = pymysql.connect(host='localhost',port=3306,user='root',password='12345',db='test_Mysql')
cursor = db.cursor() # 获取操作游标
# 创建表
sql = '''create table if not exists students (id varchar(15) not null, name varchar(255) not null, age INT not null, primary key(id))'''
cursor.execute(sql)
db.close()
插入数据
id = '20120203'
name = 'Li'
age = 18
sql = '''insert into students(id,name,age) values(%s,%s,%d)''' # 格式化字符%s代替value值
try:
cursor.execute(sql,(id,name,age))# 第一个参数传入sql语句,第二个参数传入value值,用元组的方式
db.commit() # 提交事务
except:
db.rollback() # 错误回滚
db.close()
事物的四个属性:
属性 | 解释 |
---|---|
原子性 | 事务是一个不可分割的工作单位,事务中包括的注入操作要么都做,要么都不做 |
一致性 | 一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。举例来说,假设用户A和用户B两者的钱加起来一共是1000,那么不管A和B之间如何转账、转几次账,事务结束后两个用户的钱相加起来应该还得是1000,这就是事务的一致性 |
隔离性 | 隔离性是当多个用户并发访问数据库时,比如同时操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。关于事务的隔离性数据库提供了多种隔离级别 |
持久性 | 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。 |
--------- | ------------------------------ |
插入,更新,删除操作都是对数据库进行更改的操作,而更改操作偶必须为一个事务,所以这些操作的标准写法就是:
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()
插入数据还可以利用 dict 字典的形式
实现动态插入,这种方式对于***Python爬虫数据采集***很方便
data = {
'id': '123456',
'name':‘ligang’
'age':20
}
table = 'students'
keys = ','.join(data.keys())
values = ','.join(['%s']*len(data))
sql = 'insert into {table}({keys}) values ({values})'.format(table=table, keys=keys,values=values)
try:
if cursor.execute(sql, tuple(data.values())):
print('Successful')
db.commit()
except:
print('Filed')
db.close()
更新数据
sql = ‘update students set age = %s where name = %s’
cursor.execute(sql, (20,'Bob'))
查询
sql = 'select * from students where age>=20'
print('row count:', cursor.execute(sql))
cursor.fetchone() # 获取一条
cursor.fetchall() # 获取剩余全部 ,二重元组的形式,如果数据量大,内存开销便会增大
Python操作MongoDB
- 连接MongoDB
from pymongo import MongoClient
from datetime import datetime
# 方式1
# client = MongoClient()
# 方式2
# client2 = MongoClient('localhost',27017)# ip, 端口
# 方式三
# client3 = MongoClient('mongodb://localhost:27017')# 直接传入字符串mongodb开头
# print(client2.HOST)
# print(client.list_database_names())
# client.close() # 关闭依然可以用。自带线程池 当重新访问 数据库会自动连接
# print(client.list_database_names())
- 操作增删改查
** ****** 将连接封装成为类,用面向对象的方式去调用方法 ***** **
class TetMongo(object):
def __init__(self):
self.client = MongoClient() # 建立连接 默认本地
# self.db = self.client['test'] # 没有自动创建
self.db = self.client.test # 链接数据库 和上边一样
def add_one(self):
"""新增数据"""
student = {
'id': '135136',
'name': '老李',
'age': '22',
'gender': '男',
'time': datetime.now() # 自动添加字段,这个时间可以用原生的python时间不需要加处理
}
return self.db.students.insert_one(student)
# 除了插入一条之外 insert插入多条采用【{stu1},{stu2}】列表嵌套字典的方式
# save() 也可以保存多条,但是要遍历列表 速度慢
def get_one_from_id(self,stu_id):
'''查询指定id的数据'''
return self.db.students.find_one({'id':str(stu_id)}) # 查找一条 find_one
def get_more_from_gender(self,gender):
'''查询多个性别为男的数据'''
return self.db.students.find({'gender':str(gender)}) # 查找多条 find
def find_all(self):
return self.db.students.find() # 直接调用不传参数 默认查找该集合全部数据
# (>) 大于 - $gt
# (<) 小于 - $lt
# (>=) 大于等于 - $gte
# (<= ) 小于等于 - $lte
# 例:查询集合中age大于25的所有记录
# for i in my_set.find({"age": {"$gt": 25}}):
# print(i)
def update_from_id(self):
rest = self.db.students.update_one({'name':'老王'},{'$set':{'gender':'女'}})
# rest = self.db.students.update_many({},{'$set':{'gender':'女'}})
print(rest)
def remove(self):
# return self.db.students.delete_one({'id':str(id)}) # 删除一条
return self.db.students.remove() # 删除所有记录
# return self.db.students.remove({'name':'老王'})
def main():
obj = TetMongo()
# result = obj.add_one()
# print(result.inserted_id)
# result = obj.get_one_from_id(123415)
# print(result)
#
result_list = obj.get_more_from_gender('男')
for res in result_list:
print(res)
# all_stu = obj.find_all()
# for res in all_stu:
# print(res)
# # obj.update_from_id()
#
res1=obj.remove()
print(res1)
if __name__ == '__main__':
main()
Python操作Redis
- 简单模式
from redis import StrictRedis, ConnectionPool
redis_url="redis://:xxxx@112.27.10.168:6379/15"
pool = ConnectionPool.from_url(redis_url, decode_responses=True)
r= StrictRedis(connection_pool=pool)
- 简单封装
REDIS_URL = 'redis://:{password}@{host}:{port}/{db}'.format(
**DEFAULT_REDIS_CONF)
def operator_status(func):
"""
get operatoration status
"""
def gen_status(*args, **kwargs):
error, result = None, None
try:
result = func(*args, **kwargs)
except Exception as e:
error = str(e)
return {'result': result, 'error': error}
return gen_status
class Es2Redis:
def __init__(self):
if not hasattr(Es2Redis, 'pool'):
Es2Redis.create_pool()
self._connection = redis.Redis(connection_pool=Es2Redis.pool)
@staticmethod
def create_pool():
Es2Redis.pool = redis.ConnectionPool.from_url(REDIS_URL, decode_components=True)
@operator_status
def set_data(self, key, value):
"""
set data with (key, value)
"""
return self._connection.set(key, value)
@operator_status
def get_data(self, key):
"""
get data by key
"""
return self._connection.get(key)
@operator_status
def del_data(self, key):
"""
delete cache by key
"""
return self._connection.delete(key)