建立数据库mariadb_learn,并且在userinfor表里面写入20个用户的账号和密码信息。代码如下
import pymysql
#随机生成20条用户数据; 列表里面嵌套元组;
list_infor = [('user'+str(num),'00000')for num in range(1,21)]
dbconfig = {
'host' :'localhost',
'user' : 'root',
'passwd' : '123456',
'db' :'mariadb_learn'
}
# 1. 连接数据库连接
conn = pymysql.connect(**dbconfig)
# 2. 创建游标, 给数据库发送sql指令
cur = conn.cursor()
try:
insert_sqli = 'insert into userinfor values(%s,%s)'
cur.executemany(insert_sqli,list_infor)
except Exception as Error:
print('sql exrcutemany failed:',Error)
else:
print('sql executeamny success!')
# 4. 提交sql语句, 作用于数据库;
conn.commit()
# 5. 先关闭游标
cur.close()
# 6. 关闭数据库连接
conn.close()
输出
sql executeamny success!
再次使用executemany()函数将前5到15条用户信息的密码更改为123456。
import pymysql
dbconfig = {
'host' :'localhost',
'user' : 'root',
'passwd' : '123456',
'db' :'mariadb_learn'
}
#随机生成20条用户数据; 列表里面嵌套元组;
list_infor = [('user'+str(num),'00000')for num in range(1,21)]
update_infor = [userinfor[0] for userinfor in list_infor[4:15]]
#1.数据库连接
conn = pymysql.connect(**dbconfig)
#2.创建游标,用于给数据库发送sql指令
cur = conn.cursor()
#3.执行sql语句 : 一次性插入多条信息
try:
update_sqli = 'update userinfor set passwd = "13324" where username = %s'
cur.executemany(update_sqli, update_infor)
except Exception as Error:
print('sql update failed',Error)
else:
print('sql update success')
#4 . 提交sql语句,作用于数据库
conn.commit()
#5.关闭游标
cur.close()
#6.关闭数据库
conn.close()
输出:
sql update success
当我们使用fetchone()、fetchaall()、fetchmany()三个函数去查看表的内容时、我们表的游标跟随查看的位置进行移动,这一点有点类似于我们文件读写时候的一个指针,这个指针来确定当前读写文件内容的位置。
fetchall()函数用于读取表格的一行,以元组的形式返回当前行的信息,游标进入下一行。
fetchmany()函数用于读取指定的表的行数,以嵌套元组的形式返回,指定行的信息。
fetchall()函数用于读写当前游标所在位置到白结尾的所有行,以嵌套元组的形式返回所有的信息。
scroll(value, mode='relative') #mode的默认值是 'relative' 代表游标相对于当前位置移动value行
#mode也可以取值为'absolute' 代表游标移动到表的第value行
scroll()函数用于读取表内容时移动游标的位置。
import pymysql
dbconfig = {
'host' :'localhost',
'user' : 'root',
'passwd' : '123456',
'db' :'mariadb_learn'
}
# 1. 连接数据库连接
conn = pymysql.connect(**dbconfig)
# 2. 创建游标, 给数据库发送sql指令
cur = conn.cursor()
# 3. 执行sql语句: 查看数据
cur.execute('select * from userinfor;')
print(cur.fetchone())
print(cur.fetchone())
print(cur.fetchmany(5))
cur.scroll(0,'absolute')
print(cur.fetchall())
cur.close()
conn.close()
输出:
('user1', '00000')
('user2', '00000')
(('user3', '00000'), ('user4', '00000'), ('user5', '13324'), ('user6', '13324'), ('user7', '13324'))
(('user1', '00000'), ('user2', '00000'), ('user3', '00000'), ('user4', '00000'), ('user5', '13324'), ('user6', '13324'), ('user7', '13324'), ('user8', '13324'), ('user9', '13324'), ('user10', '13324'), ('user11', '13324'), ('user12', '13324'), ('user13', '13324'), ('user14', '13324'), ('user15', '13324'), ('user16', '00000'), ('user17', '00000'), ('user18', '00000'), ('user19', '00000'), ('user20', '00000'))
import pymysql
dbconfig = {
'host' :'localhost',
'user' : 'root',
'passwd' : '123456',
'db' :'mariadb_learn'
}
# 1. 连接数据库连接
conn = pymysql.connect(**dbconfig)
# 2. 创建游标, 给数据库发送sql指令
cur = conn.cursor()
# 3. 执行sql语句: 查看数据
cur.execute('select * from userinfor;')
try:
with open('/tmp/userinfor','w') as file_it:
for row_infor in cur.fetchall():
file_it.write(':'.join(row_infor)+'\n')
except Exception as Error:
print(Error)
else:
print("success")
finally:
cur.close()
conn.close()
description用于获取表头信息,将表头信息以嵌套元组的形式返回,类似于数据库中的命名desc
import pymysql
dbconfig = {
'host' :'localhost',
'user' : 'root',
'passwd' : '123456',
'db' :'mariadb_learn'
}
# 1. 连接数据库连接
conn = pymysql.connect(**dbconfig)
# 2. 创建游标, 给数据库发送sql指令
cur = conn.cursor()
# 3. 执行sql语句: 查看数据
cur.execute('select * from userinfor;')
print(cur.description)
cur.close()
conn.close()
输出:
(('username', 253, None, 10, 10, 0, True), ('passwd', 253, None, 10, 10, 0, True))
conn = pymysql.connect(
'host' ='localhost',
'user' = 'root',
'passwd' = '123456',
'db' ='mariadb_learn')
with conn: cur = conn.cursor() 使用with上下文管理器,可以有助于我们简化代码,将关闭游标和关闭数据库连接的工作交给解释器自己去完成。
import pymysql
import os
dbconfig = {
'host': 'localhost',
'user': 'root',
'passwd': '123456',
'db': 'mariadb_learn'}
#第归扫描得到指定文件目录下的所有文件,#所有的.jpg图片的文件名存入列表
def SearchAbsPath(dirname):
dirname = os.path.abspath(dirname)
filenames = list()
for root, dirs, files in os.walk(dirname, topdown=False): # 扫描一层目录
for name in files:
filenames.append(root + os.path.sep + name) # 每一个文件的绝对路径放入列表
images = [image_file for image_file in filenames if image_file.endswith('.jpg')]
return images
# 将所有的图片存入到数据库中
def insert_images(**kwargs):
# 1. 连接数据库连接
conn = pymysql.connect(**kwargs)
# 2. 创建游标,给数据库发送sql指令
cur = conn.cursor()
def create_connt():
try:
cur.execute('create table images('
'id int primary key auto_increment , '
'imgName varchar(50),'
'imgData mediumblob);')
# id int primary key auto_increment 这一列的表头信息为id 整形数,即图片的id,
# primary key :作为该表的主键, auto_increment : id 可由系统随机生成
# imgName 图片的名字
# imgData mediumblob 存储的图片,imgData 为表头,mediumblob以二进制中等大小文件形式存储。
except Exception as Eorr:
raise Eorr
else:
print('table create sucess!')
create_connt()
try:
insert_sqli = 'insert into images (imgName, imgData) values(%s, %s);'
for images in SearchAbsPath('/tmp/images/'):
file_it = open(images, 'rb')
img_data = file_it.read()
file_it.close()
cur.execute(insert_sqli,(images,img_data))
except Exception as Eorr:
raise Eorr
else:
print("插入图片信息成功!")
finally:
conn.commit()
cur.close()
conn.close()
insert_images(**dbconfig)
import pymysql
import os
def decode(s):
return ''.join([chr(i) for i in [int(b, 2) for b in s.split(' ')]])
dbconfig = {'host' : 'localhost',
'user' : 'root',
'passwd': '123456',
'db' : 'mariadb_learn'}
def DownLoad_Image_from_db(download_dir='/tmp/download/',**kwargs):
"""
:param download_dir: 从数据库中读取的图片的保存到本地的目录
:param kwargs: 数据连接的参数
:return:
"""
conn = pymysql.connect(**kwargs)
cur = conn.cursor()
cur.execute('select * from images')
while True:
# 使用fetchone 可以保证内存不会因为一次性读取的图片内存过大,而导致内存崩溃
row = cur.fetchone()
#row是三个元素的元组分别是id,imgName、imgData
if row != None:
with open(download_dir+os.path.split(row[1])[1],'wb') as fileit_img:
fileit_img.write(row[2])
pass
else:
break
cur.close()
conn.close()
DownLoad_Image_from_db(**dbconfig)
如果我们拥有所有权限,那么我们可以使用远程登录某台主机上的数据库,比如:
mysql -h 192.168.3.25 -uroot -p123456
以root用户的身份使用密码123456 区远程登录192.168.3.25这台主机的数据库,如果我们登录成功,就会拥有root的全部权限。但是为了数据安全,我们不会让别人去使用root用户的身份去远程连接登陆我们的数据库,经常是创建一些普通用户,然后对该用户的权限进行限制后,交于别人远程登录数据库。
#创建一个密码为123456的userone用户,只能在本地对数据库进行访问。
create user userone@localhost identfiend by '123456'
#创建一个密码为123456的userone用户,只能在ip为192.163.3.15的主机上访问我的数据库
create user [email protected] identfied by '123456'
#创建一个密码为123456的userone用户,可以在所有的ip上访问我的数据库。
create user userone@'%' identified by '123456'
#创建无密码的userone用户,可以在所有的ip上访问我的数据库。
create user userone@'%'
grant <权限> on <数据库>.<表> to <用户>@
#让userone用户在本地连接数据库时,
#对mariadb_learn数据库中的userinfor
#表拥有insert,update、delete、select、create权限
grant (insert,update,delete,select,create) on mariadb_learn.userinfor to userone@localhost;
当我们设定了用户的权限后,需要重读授权表。
flush privileges; #重读用户授权表
how grants for userone@localhost; #查看userone用户的授权表。
revoke delete,update on mariadb_learn.* from userinfor@localhost; #删除用户的指定权限。
drop user userone@localhost #删除userone用户。
· #对mariadb_learn数据库进行备份.
mysqldump -uroot -p mariadb_learn > mariadb_learn.dump
#对mariadb_learn数据库中进行不要数据的备份
mysqldump -uroot -p123456 --no-data mariadb_learn > `date +%Y_%m_%d`_mariadb_learn.dump
对所有的数据库进行备份
mysqldump -uroot -p123456 --all-databases > mariadb_learn.dump
#1、新建数据库
mysql -uroot -p123456 create mariadb_learn2
#2、恢复
mysql -uroot -p 123456 mariadb_learn2 < mariadb_learn.dump
import os
import time
from mysqlInfo import mysql_list
BACKUP_DIR = '/mnt/BACKUP/'
if not os.path.exists(BACKUP_DIR):
os.mkdir(BACKUP_DIR)
print("%s create success!" % (BACKUP_DIR))
else:
try:
for host in mysql_list:
# date = os.popen('date +%Y_%m_%d')
shell_sen = "mysqldump -h %s -u%s -p%s %s >%s"
host_ip = host['host']
user = host['user']
passwd = host['passwd']
db = host['db']
backup_filename = BACKUP_DIR + '%s_%s.dump' %(host_ip, db)
print(backup_filename)
print(shell_sen % (host_ip, user, passwd, db, backup_filename))
os.system(shell_sen % (host_ip, user, passwd, db, backup_filename))
print("backup %s host" %(host_ip))
except Exception as e:
print(e)
else:
print('sucess')
os.system(str) 是的字符命令在shell环境中进行运行。
银行转账时,本质就是对数据库中的数据进行加减法,但是当我们在转账的中途突然断电了怎么办,这里就需要用到数据库的执行事务。
事务机制可以保证数据的一致性。
失误应该具有4个属性:原子性、一致性、隔离性、持久性。这四个数次那个通常称为ACID特性。
*原子性(atomicity)。一个事物是一个可分割的工作单位,事物中包括的诸操作要么都做,要么都不做。
*一致性(consistency)。事物必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
*隔离性(isolation)。一个事物的执行不能被其他事物干扰。即一个事物内部的操作及使用的数据对并发的其他事物是隔
离的,并发执行的各个事物之间不能相互干扰
*持久性(durability)。持续性也称为持久性,只一个事务一旦提交,他对数据库中数据的改变就应该是永久性的。接下来
的其他操作或故障不应该对其有任何影响。
Python DB API 2.0 的事务提供了两个方法 commit 或 rollback。
对于支持事务的数据库, 在Python数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。commit()方法游标的所有更新操作,rollback()方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。
import pymysql
import sys
class TransferMoney(object):
def __init__(self,conn):
self.conn = conn
def transfer(self,source_acctid,target_asstid,money):
"""
转账函数
:param source_acctid:
:param target_asstid:
:param money:
:return:
"""
try :
self.check_acct_available(source_acctid)
self.check_acct_available(target_asstid)
self.has_enough_money(source_acctid,money)
self.reduce_money(source_acctid,money)
self.add_money(target_asstid,money)
self.conn.commit()
except Exception as Error:
self.conn.rollback() #数据库的方法,撤销前面对数据库的操作
raise (Error)
def check_acct_available(self,acctid):
"""
检查账户是否存在
:param acctid: 需要被检查的账户
:return:
"""
cur = self.conn.cursor() #数据库游标建立
try:
select_sql = 'select * from account where accid = %s;'%(acctid)
cur.execute(select_sql)
print("execute aql :%s"%(select_sql))
res = cur.fetchall()
if len(res) != 1:
raise Exception('账号%s不存在'%(acctid))
except Exception as Error:
raise (Error)
finally:
cur.close()
def has_enough_money(self, acctid, money):
"""
检查账户是否有足够的金钱
:param acctid: 当前账户
:param money: 需要判断的的金额
:return:
"""
cur = self.conn.cursor()
try:
select_sql = 'select money from account where accid = %s'%(acctid)
cur.execute(select_sql)
print('has_enough_money aql:%s'%(select_sql))
res = cur.fetchall()
if res:
now_money = res[0][0]
if now_money < int(money):
raise Exception('账户%s没有足够的钱,目前金额为%s',acctid,money)
except Exception as Error:
raise (Error)
finally:
cur.close()
def reduce_money(self, acctid, money):
"""
对账户的减去指定的金额
:param acctid: 账户
:param money: 减去的金额
:return:
"""
cur = self.conn.cursor()
try:
update_sqli = 'update account set money = money-%s where accid = %s'%(money,acctid)
cur.execute(update_sqli)
print('add_money sql:%s'%(update_sqli))
except Exception as Error:
raise (Error)
finally:
cur.close()
def add_money(self, asstid, money):
"""
指定账户增加相应的钱数
:param asstid: 增加金额的账户
:param money: 增加的金额
:return:
"""
cur = self.conn.cursor()
try:
update_sqli = 'update account set money = money+%s where accid = %s'%(money,asstid)
cur.execute(update_sqli)
print('add_money sql:%s'%(update_sqli))
except Exception as Error:
raise (Error)
finally:
cur.close()
def main():
db_dict ={'host' :'localhost',
'user' : 'root',
'passwd' : '123456',
'db' :'mariadb_learn'}
conn = pymysql.connect(**db_dict)
trans_money = TransferMoney(conn)
source_acctid = sys.argv[1]
target_acctid = sys.argv[2]
money = sys.argv[3]
try :
trans_money.transfer(source_acctid,target_acctid,money)
except Exception as Eorr:
print (Eorr)
finally:
conn.close()
if __name__ == '__main__':
main()
数据库中的初始账号和钱数如下:
在shell里面运行该文件上面源代码的文件,并加上参数,即621700账户向621701账户转账500元
两个账户在数据库中的进而已经减少