python数据库操作 如何使用python对数据库(mysql)进行操作
大家好,感谢邀请,今天来为大家分享一下python数据库操作的问题,以及和如何使用python对数据库(mysql)进行操作的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!
如何使用python对数据库(mysql)进行操作
一、数据库基本操作
1.想允许在数据库写中文,可在创建数据库时用下面命令
create database zcl charset utf8;2.查看students表结构
desc students;3.查看创建students表结构的语句
show create table students;4.删除数据库
drop database zcl;5.创建一个新的字段
alter table students add column nal char(64);PS:本人是很讨厌上面这种“简单解释+代码”的博客。其实我当时在mysql终端写了很多的实例,不过因为当时电脑运行一个看视频的软件,导致我无法Ctrl+C/V。现在懒了哈哈~~
二、python连接数据库python3不再支持mysqldb。其替代模块是PyMySQL。本文的例子是在python3.4环境。
1.安装pymysql模块
pip3 install pymysql2.连接数据库,插入数据实例
import pymysql
#生成实例,连接数据库zcl
conn= pymysql.connect(host='127.0.0.1', user='root', passwd='root', db='zcl')
#生成游标,当前实例所处状态
cur= conn.cursor()
#插入数据
reCount= cur.execute('insert into students(name, sex, age, tel, nal) values(%s,%s,%s,%s,%s)',('Jack','man',25,1351234,"CN"))
reCount= cur.execute('insert into students(name, sex, age, tel, nal) values(%s,%s,%s,%s,%s)',('Mary','female',18,1341234,"USA"))
conn.commit()#实例提交命令
cur.close()
conn.close()
print(reCount)查看结果:
mysql> select* from students;+----+------+-----+-----+-------------+------+
| id| name| sex| age| tel| nal|
+----+------+-----+-----+-------------+------+
| 1| zcl| man| 22| 15622341234| NULL|
| 2| alex| man| 30| 15622341235| NULL|
+----+------+-----+-----+-------------+------+
2 rows in set3.获取数据
import pymysql
conn= pymysql.connect(host='127.0.0.1', user='root', passwd='root', db='zcl')
cur= conn.cursor()
reCount= cur.execute('select* from students')
res= cur.fetchone()#获取一条数据
res2= cur.fetchmany(3)#获取3条数据
res3= cur.fetchall()#获取所有(元组格式)
print(res)
print(res2)
print(res3)
conn.commit()
cur.close()
conn.close()输出:
(1,'zcl','man', 22,'15622341234', None)
((2,'alex','man', 30,'15622341235', None),(5,'Jack','man', 25,'1351234','CN'),(6,'Mary','female', 18,'1341234','USA'))
()三、事务回滚事务回滚是在数据写到数据库前执行的,因此事务回滚conn.rollback()要在实例提交命令conn.commit()之前。只要数据未提交就可以回滚,但回滚后ID却是自增的。请看下面的例子:
插入3条数据(注意事务回滚):
import pymysql
#连接数据库zcl
conn=pymysql.connect(host='127.0.0.1', user='root', passwd='root', db='zcl')
#生成游标,当前实例所处状态
cur=conn.cursor()
#插入数据
reCount=cur.execute('insert into students(name, sex, age, tel, nal) values(%s,%s,%s,%s,%s)',('Jack','man', 25, 1351234,"CN"))
reCount=cur.execute('insert into students(name, sex, age, tel, nal) values(%s,%s,%s,%s,%s)',('Jack2','man', 25, 1351234,"CN"))
reCount=cur.execute('insert into students(name, sex, age, tel, nal) values(%s,%s,%s,%s,%s)',('Mary','female', 18, 1341234,"USA"))
conn.rollback()#事务回滚
conn.commit()#实例提交命令
cur.close()
conn.close()
print(reCount)未执行命令前与执行命令后(包含回滚操作)(注意ID号):未执行上面代码与执行上面代码的结果是一样的!!因为事务已经回滚,故students表不会增加数据!
mysql> select* from students;+----+------+--------+-----+-------------+------+
| id| name| sex| age| tel| nal|
+----+------+--------+-----+-------------+------+
| 1| zcl| man| 22| 15622341234| NULL|
| 2| alex| man| 30| 15622341235| NULL|
| 5| Jack| man| 25| 1351234| CN|
| 6| Mary| female| 18| 1341234| USA|
+----+------+--------+-----+-------------+------+
4 rows in set执行命令后(不包含回滚操作):只需将上面第11行代码注释。
mysql> select* from students;+----+-------+--------+-----+-------------+------+
| id| name| sex| age| tel| nal|
+----+-------+--------+-----+-------------+------+
| 1| zcl| man| 22| 15622341234| NULL|
| 2| alex| man| 30| 15622341235| NULL|
| 5| Jack| man| 25| 1351234| CN|
| 6| Mary| female| 18| 1341234| USA|
| 10| Jack| man| 25| 1351234| CN|
| 11| Jack2| man| 25| 1351234| CN|
| 12| Mary| female| 18| 1341234| USA|
+----+-------+--------+-----+-------------+------+
7 rows in set总结:虽然事务回滚了,但ID还是自增了,不会因回滚而取消,但这不影响数据的一致性(底层的原理我不清楚~)
四、批量插入数据import pymysql
#连接数据库zcl
conn= pymysql.connect(host='127.0.0.1', user='root', passwd='root', db='zcl')
#生成游标,当前实例所处状态
cur= conn.cursor()
li= [
("cjy","man",18,1562234,"USA"),
("cjy2","man",18,1562235,"USA"),
("cjy3","man",18,1562235,"USA"),
("cjy4","man",18,1562235,"USA"),
("cjy5","man",18,1562235,"USA"),
]
#插入数据
reCount= cur.executemany('insert into students(name,sex,age,tel,nal) values(%s,%s,%s,%s,%s)', li)
#conn.rollback()#事务回滚
conn.commit()#实例提交命令
cur.close()
conn.close()
print(reCount)pycharm下输出: 5
mysql终端显示:
mysql> select* from students;#插入数据前+----+-------+--------+-----+-------------+------+
| id| name| sex| age| tel| nal|
+----+-------+--------+-----+-------------+------+
| 1| zcl| man| 22| 15622341234| NULL|
| 2| alex| man| 30| 15622341235| NULL|
| 5| Jack| man| 25| 1351234| CN|
| 6| Mary| female| 18| 1341234| USA|
| 10| Jack| man| 25| 1351234| CN|
| 11| Jack2| man| 25| 1351234| CN|
| 12| Mary| female| 18| 1341234| USA|
+----+-------+--------+-----+-------------+------+
7 rows in set
mysql> mysql> select* from students;#插入数据后+----+-------+--------+-----+-------------+------+
| id| name| sex| age| tel| nal|
+----+-------+--------+-----+-------------+------+
| 1| zcl| man| 22| 15622341234| NULL|
| 2| alex| man| 30| 15622341235| NULL|
| 5| Jack| man| 25| 1351234| CN|
| 6| Mary| female| 18| 1341234| USA|
| 10| Jack| man| 25| 1351234| CN|
| 11| Jack2| man| 25| 1351234| CN|
| 12| Mary| female| 18| 1341234| USA|
| 13| cjy| man| 18| 1562234| USA|
| 14| cjy2| man| 18| 1562235| USA|
| 15| cjy3| man| 18| 1562235| USA|
| 16| cjy4| man| 18| 1562235| USA|
| 17| cjy5| man| 18| 1562235| USA|
+----+-------+--------+-----+-------------+------+
12 rows in set学完的东西要及时总结,有些东西忘记了阿~_~
python对数据库表格里面的内容增删查改怎么写
本文主要给大家介绍了关于python模拟sql语句对员工表格进行增删改查的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:
具体需求:
员工信息表程序,实现增删改查操作:
可进行模糊查询,语法支持下面3种:
select name,age from staff_data where age> 22多个查询参数name,age用','分割
select* from staff_data where dept=人事
select* from staff_data where enroll_date like 2013
查到的信息,打印后,最后面还要显示查到的条数
可创建新员工纪录,以phone做唯一键,phone存在即提示,staff_id需自增,添加多个记录record1/record2中间用'/'分割
insert into staff_data values record1/record2
可删除指定员工信息纪录,输入员工id,即可删除
delete from staff_data where staff_id>=5andstaff_id<=10
可修改员工信息,语法如下:
update staff_table set dept=Market,phone=13566677787 where dept=运维多个set值用','分割
使用re模块,os模块,充分使用函数精简代码,熟练使用 str.split()来解析格式化字符串
由于,sql命令中的几个关键字符串有一定规律,只出现一次,并且有顺序!!!
按照key_lis= ['select','insert','delete','update','from','into','set','values','where','limit']的元素顺序分割sql.
分割元素作为sql_dic字典的key放进字典中.分割后的列表为b,如果len(b)>1,说明sql字符串中含有分割元素,同时b[0]对应上一个分割元素的值,b[-1]为下一次分割对象!
这样不断迭代直到把sql按出现的所有分割元素分割完毕,但注意这里每次循环都是先分割后赋值!!!当前分割元素比如'select'对应的值,需要等到下一个分割元素
比如'from'执行分割后的列表b,其中b[0]的值才会赋值给sql_dic['select'],所以最后一个分割元素的值,不能通过上述循环来完成,必须先处理可能是最后一个分割元素,再正常循环!!
在这sql语句中,有可能成为最后一个分割元素的'limit','values','where',按优先级别,先处理'limit',再处理'values'或'where'.....
处理完得到sql_dic后,就是你按不同命令执行,对数据文件的增删改查,最后返回处理结果!!
示例代码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
# _*_coding:utf-8_*_# Author:Jaye Heimport reimport os def sql_parse(sql, key_lis):'''解析sql命令字符串,按照key_lis列表里的元素分割sql得到字典形式的命令sql_dic:param sql::param key_lis::return:''' sql_list= [] sql_dic={} for i in key_lis: b= [j.strip() for j in sql.split(i)] if len(b)> 1: if len(sql.split('limit'))> 1: sql_dic['limit']= sql.split('limit')[-1] if i=='where' or i=='values': sql_dic[i]= b[-1] if sql_list: sql_dic[sql_list[-1]]= b[0] sql_list.append(i) sql= b[-1] else: sql= b[0] if sql_dic.get('select'): if not sql_dic.get('from') and not sql_dic.get('where'): sql_dic['from']= b[-1] if sql_dic.get('select'): sql_dic['select']= sql_dic.get('select').split(',') if sql_dic.get('where'): sql_dic['where']= where_parse(sql_dic.get('where')) return sql_dic def where_parse(where):'''格式化where字符串为列表where_list,用'and','or','not'分割字符串:param where::return:''' casual_l= [where] logic_key= ['and','or','not'] for j in logic_key: for i in casual_l: if i not in logic_key: if len(i.split(j))> 1: ele= i.split(j) index= casual_l.index(i) casual_l.pop(index) casual_l.insert(index, ele[0]) casual_l.insert(index+1, j) casual_l.insert(index+2, ele[1]) casual_l= [k for k in casual_l if k] where_list= three_parse(casual_l, logic_key) return where_list def three_parse(casual_l, logic_key):'''处理临时列表casual_l中具体的条件,'staff_id>5'-->['staff_id','>','5']:param casual_l::param logic_key::return:''' where_list= [] for i in casual_l: if i not in logic_key: b= i.split('like') if len(b)> 1: b.insert(1,'like') where_list.append(b) else: key= ['<','=','>'] new_lis= [] opt='' lis= [j for j in re.split('([=<>])', i) if j] for k in lis: if k in key: opt+= k else: new_lis.append(k) new_lis.insert(1, opt) where_list.append(new_lis) else: where_list.append(i) return where_list def sql_action(sql_dic, title):'''把解析好的sql_dic分发给相应函数执行处理:param sql_dic::param title::return:''' key={'select': select,'insert': insert,'delete': delete,'update': update} res= [] for i in sql_dic: if i in key: res= key[i](sql_dic, title) return res def select(sql_dic, title):'''处理select语句命令:param sql_dic::param title::return:''' with open('staff_data','r', encoding='utf-8') as fh: filter_res= where_action(fh, sql_dic.get('where'), title) limit_res= limit_action(filter_res, sql_dic.get('limit')) search_res= search_action(limit_res, sql_dic.get('select'), title) return search_res def insert(sql_dic, title):'''处理insert语句命令:param sql_dic::param title::return:''' with open('staff_data','r+', encoding='utf-8') as f: data= f.readlines() phone_list= [i.strip().split(',')[4] for i in data] ins_count= 0 if not data: new_id= 1 else: last= data[-1] last_id= int(last.split(',')[0]) new_id= last_id+1 record= sql_dic.get('values').split('/') for i in record: if i.split(',')[3] in phone_list: print('\033[1;31m%s手机号已存在\033[0m'% i) else: new_record='%s,%s\n'%(str(new_id), i) f.write(new_record) new_id+= 1 ins_count+= 1 f.flush() return ['insert successful'], [str(ins_count)] def delete(sql_dic, title):'''处理delete语句命令:param sql_dic::param title::return:''' with open('staff_data','r', encoding='utf-8') as r_file,\ open('staff_data_bak','w', encoding='utf-8') as w_file: del_count= 0 for line in r_file: dic= dict(zip(title.split(','), line.split(','))) filter_res= logic_action(dic, sql_dic.get('where')) if not filter_res: w_file.write(line) else: del_count+= 1 w_file.flush() os.remove('staff_data') os.rename('staff_data_bak','staff_data') return ['delete successful'], [str(del_count)] def update(sql_dic, title):'''处理update语句命令:param sql_dic::param title::return:''' set_l= sql_dic.get('set').strip().split(',') set_list= [i.split('=') for i in set_l] update_count= 0 with open('staff_data','r', encoding='utf-8') as r_file,\ open('staff_data_bak','w', encoding='utf-8') as w_file: for line in r_file: dic= dict(zip(title.split(','), line.strip().split(','))) filter_res= logic_action(dic, sql_dic.get('where')) if filter_res: for i in set_list: k= i[0] v= i[-1] dic[k]= v line= [dic[i] for i in title.split(',')] update_count+= 1 line=','.join(line)+'\n' w_file.write(line) w_file.flush() os.remove('staff_data') os.rename('staff_data_bak','staff_data') return ['update successful'], [str(update_count)] def where_action(fh, where_list, title):'''具体处理where_list里的所有条件:param fh::param where_list::param title::return:''' res= [] if len(where_list)!= 0: for line in fh: dic= dict(zip(title.split(','), line.strip().split(','))) if dic['name']!='name': logic_res= logic_action(dic, where_list) if logic_res: res.append(line.strip().split(',')) else: res= [i.split(',') for i in fh.readlines()] return res pass def logic_action(dic, where_list):'''判断数据文件中每一条是否符合where_list条件:param dic::param where_list::return:''' logic= [] for exp in where_list: if type(exp) is list: exp_k, opt, exp_v= exp if exp[1]=='=': opt='==' logical_char="'%s'%s'%s'"%(dic[exp_k], opt, exp_v) if opt!='like': exp= str(eval(logical_char)) else: if exp_v in dic[exp_k]: exp='True' else: exp='False' logic.append(exp) res= eval(''.join(logic)) return res def limit_action(filter_res, limit_l):'''用列表切分处理显示符合条件的数量:param filter_res::param limit_l::return:''' if limit_l: index= int(limit_l[0]) res= filter_res[:index] else: res= filter_res return res def search_action(limit_res, select_list, title):'''处理需要查询并显示的title和相应数据:param limit_res::param select_list::param title::return:''' res= [] fields_list= title.split(',') if select_list[0]=='*': res= limit_res else: fields_list= select_list for data in limit_res: dic= dict(zip(title.split(','), data)) r_l= [] for i in fields_list: r_l.append((dic[i].strip())) res.append(r_l) return fields_list, res if __name__=='__main__': with open('staff_data','r', encoding='utf-8') as f: title= f.readline().strip() key_lis= ['select','insert','delete','update','from','into','set','values','where','limit'] while True: sql= input('请输入sql命令,退出请输入exit:').strip() sql= re.sub('','', sql) if len(sql)== 0:continue if sql=='exit':break sql_dict= sql_parse(sql, key_lis) fields_list, fields_data= sql_action(sql_dict, title) print('\033[1;33m结果如下:\033[0m') print('-'.join(fields_list)) for data in fields_data: print('-'.join(data))
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
python 怎么操作mysql中多个数据库
MySQL的 Binlog记录着 MySQL数据库的所有变更信息,了解 Binlog的结构可以帮助我们解析Binlog,甚至对 Binlog进行一些修改,或者说是“篡改”,例如实现类似于 Oracle的 flashback的功能,恢复误删除的记录,把 update的记录再还原回去等。本文将带您探讨一下这些神奇功能的实现,您会发现比您想象地要简单得多。本文指的 Binlog是 ROW模式的 Binlog,这也是 MySQL 8里的默认模式,STATEMENT模式因为使用中有很多限制,现在用得越来越少了。
Binlog由事件(event)组成,请注意是事件(event)不是事务(transaction),一个事务可以包含多个事件。事件描述对数据库的修改内容。
现在我们已经了解了 Binlog的结构,我们可以试着修改 Binlog里的数据。例如前面举例的 Binlog删除了一条记录,我们可以试着把这条记录恢复,Binlog里面有个删除行(DELETE_ROWS_EVENT)的事件,就是这个事件删除了记录,这个事件和写行(WRITE_ROWS_EVENT)的事件的数据结构是完全一样的,只是删除行事件的类型是 32,写行事件的类型是 30,我们把对应的 Binlog位置的 32改成 30即可把已经删除的记录再插入回去。从前面的“show binlog events”里面可看到这个 DELETE_ROWS_EVENT是从位置 378开始的,这里的位置就是 Binlog文件的实际位置(以字节为单位)。从事件(event)的结构里面可以看到 type_code是在 event的第 5个字节,我们写个 Python小程序把把第383(378+5=383)字节改成 30即可。当然您也可以用二进制编辑工具来改。
找出 Binlog中的大事务
由于 ROW模式的 Binlog是每一个变更都记录一条日志,因此一个简单的 SQL,在 Binlog里可能会产生一个巨无霸的事务,例如一个不带 where的 update或 delete语句,修改了全表里面的所有记录,每条记录都在 Binlog里面记录一次,结果是一个巨大的事务记录。这样的大事务经常是产生麻烦的根源。我的一个客户有一次向我抱怨,一个 Binlog前滚,滚了两天也没有动静,我把那个 Binlog解析了一下,发现里面有个事务产生了 1.4G的记录,修改了 66万条记录!下面是一个简单的找出 Binlog中大事务的 Python小程序,我们知道用 mysqlbinlog解析的 Binlog,每个事务都是以 BEGIN开头,以 COMMIT结束。我们找出 BENGIN前面的“# at”的位置,检查 COMMIT后面的“# at”位置,这两个位置相减即可计算出这个事务的大小,下面是这个 Python程序的例子。
切割 Binlog中的大事务
对于大的事务,MySQL会把它分解成多个事件(注意一个是事务 TRANSACTION,另一个是事件 EVENT),事件的大小由参数 binlog-row-event-max-size决定,这个参数默认是 8K。因此我们可以把若干个事件切割成一个单独的略小的事务
ROW模式下,即使我们只更新了一条记录的其中某个字段,也会记录每个字段变更前后的值,这个行为是 binlog_row_image参数控制的,这个参数有 3个值,默认为 FULL,也就是记录列的所有修改,即使字段没有发生变更也会记录。这样我们就可以实现类似 Oracle的 flashback的功能,我个人估计 MySQL未来的版本从可能会基于 Binlog推出这样的功能。
了解了 Binlog的结构,再加上 Python这把瑞士军刀,我们还可以实现很多功能,例如我们可以统计哪个表被修改地最多?我们还可以把 Binlog切割成一段一段的,然后再重组,可以灵活地进行 MySQL数据库的修改和迁移等工作。
python数据库操作和如何使用python对数据库(mysql)进行操作的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!