这是日常学 python 的第九篇原创文章
首先祝大家新年快乐哈! 学生的估计明天也要上课了, 工作的估计早就去上班了, 我也快要上课了, 哈哈, 新年这段时间一直没有写过文章, 一直忙于跑亲戚和学习, 感觉有点对不起关注我的粉丝所以, 今天决定抽空写一篇技术文章来给大家看看, 继上篇写了入门 mysql 之后, 还没有学习如何用 python 来操作数据库, 那我今天就带大家来学习如何用 python 操操作数据库
还有文末有福利, 这算是给大家的新年礼物 (记得点赞哦)
进入正题
工欲善其事, 必先利其器所以第一步, 我们先下载第三方库在这里, 我用到的是 pymysql 库
下载库: 在命令行输入
1pip install pymysql
下载后可检验一下是否成功下载直接在命令行进入 python 然后导库即可
1C:\Users\June>python2Python 3.6.3 |Anaconda, Inc.| (default, Oct 15 2017, 03:27:45) [MSC v.1900 64 bit (AMD64)] on win323Type "help", "copyright", "credits" or "license" for more information.4>>> import pymysql5>>>
看到这个画面就说明下载成功了, 接下来学习如何操作数据库了!!!
1
连接数据库
1import pymysql2# 连接数据库 3db = pymysql.connect(host='127.0.0.1',user='root',passwd='your password',db='news',port=3306,charset='utf8')
以上的参数是必填的,
host: 这个是 ip 地址, 因为我这里是本地的, 所以填 127.0.0.1, 也可以填 localhost
user: 用户名, 如果你也是本地的, 就填 root 好了
passwd: 这个是密码, 填上你自己设的密码就可以了
db: 这个是数据库名, 我这里选的是 news 数据库
port: 这个是端口, 本地的一般都是 3306
charset: 这个是编码方式, 要和你数据库的编码方式一致, 要不会连接失败
连接上了, 怎么验证呢? 这里我们可以选择查一条数据
1try: 2 db = pymysql.connect(host='127.0.0.1',user='root',passwd='your password',db='news',port=3306,charset='utf8') 3 # 检验数据库是否连接成功 4 cursor = db.cursor() 5 # 这个是执行 sql 语句, 返回的是影响的条数 6 data = cursor.execute('SELECT * FROM `new`') 7 # 得到一条数据 8 one = cursor.fetchone() 9 print(data)10 print(one)11except pymysql.Error as e:12 print(e)13 print('操作数据库失败')14finally:15 # 如果连接成功就要关闭数据库 16 if db:17 db.close()
代码解读: 因为在连接数据库中, 有时会发生连接失败等异常, 所以这里就进行捕捉异常, 这里的异常都是在 pymsql.Error 里面上面的代码看不懂也没关系, 因为我接下来会说, 如果运行后有结果证明连接成功
在用完后, 一定要记得关闭数据库连接, 防止资源泄露问题
2
对数据进行查询
1import pymysql 2try: 3 conn = pymysql.connect(host='127.0.0.1',user='root',passwd='password',db='news',charset='utf8',port=3306) 4 # 这个是光标, 用来操作数据库语句 5 cursor = conn.cursor() 6 # 执行 sql 语句 7 cursor.execute('SELECT * FROM `new`') 8 print(cursor.fetchone()) 9 # 关闭光标 10 cursor.close()11except pymysql.Error as e:12 print(e)13 print('操作数据库失败')14finally:15 if conn:16 conn.close()
代码解读:
cursor(): 这个是光标, 用来执行 mysql 语句的, 用完后也是需要关闭的
excute(): 这个是执行语句, 执行参数的 mysql 语句
fetchone(): 这个是查看执行语句后的一条数据
fetchall(): 这个是查看所有数据
在查询数据后, 返回的是一整条数据, 有没有可以按字典形式来查询的呢? 来试试!
1print(cursor.fetchone()['name'])23Traceback (most recent call last):4 File "E:/anaconda/python_project/mysql_test/test2.py", line 8, in <module>5 print(cursor.fetchone()['name'])6TypeError: tuple indices must be integers or slices, not str
查了之后, 编译器想都不想就给了我这个错误, 说这是个元组, 不能这样操作
虽然 python 没有提供, 但是我们可以手动转成字典来查询啊
cursor 这里有个属性: description 获取的是数据库每个栏位情况, 如下:
1print(cursor.description)2# 下面是结果 3(('id', 3, None, 11, 11, 0, False), ('type', 253, None, 5, 5, 0, False), ('title', 253, None, 50, 50, 0, False), ('content', 253, None, 2000, 2000, 0, False), ('view_count', 3, None, 11, 11, 0, False), ('release_time', 12, None, 19, 19, 0, False), ('author', 253, None, 20, 20, 0, True), ('from', 253, None, 20, 20, 0, True), ('is_valibale', 3, None, 11, 11, 0, False)
所以, 我们利用这个属性手动生成字典
1# 将一条数据转成字典方便查找 2new = dict(zip([x[0] for x in cursor.description],[x for x in cursor.fetchone()]))3print(new)4# 下面是结果 5{'id': 2, 'type': 'NBA', 'title': '考辛斯跟腱撕裂赛季报销 浓眉詹皇发声祝福', 'content': '他遭遇左脚跟腱撕裂, 将缺席赛季剩下的比赛这无疑对考辛斯和鹈鹕队都是一个重大的打击', 'view_count': 3560, 'release_time': datetime.datetime(2018, 1, 27, 12, 10), 'author': 'xiaoylin', 'from': '腾讯体育', 'is_valibale': 1}
这里利用 zip 函数和列表生成式来一行代码就生成成功了
用字典来查询, 现在就可以了
1print(new['title'])2# 下面是结果 3 考辛斯跟腱撕裂赛季报销 浓眉詹皇发声祝福
但是, 上面的只是一条数据的, 如果是多条的呢? 再按上面的方法就行不通了这时就需要用到 map 函数了
1def new2dict(new):2 return dict(zip([x[0] for x in cursor.description],[x for x in new]))3news_list = list(map(new2dict,cursor.fetchall()))4print(news_list)5# 下面是结果 6[{'id': 2, 'type': 'NBA', 'title': '考辛斯跟腱撕裂赛季报销 浓眉詹皇发声祝福', 'content': '他遭遇左脚跟腱撕裂, 将缺席赛季剩下的比赛这无疑对考辛斯和鹈鹕队都是一个重大的打击', 'view_count': 3560, 'release_time': datetime.datetime(2018, 1, 27, 12, 10), 'author': 'xiaoylin', 'from': '腾讯体育', 'is_valibale': 1}, {'id': 3, 'type': 'NBA', 'title': '火箭挖 21 分大哈登得背锅 连遭浓眉大帽太尴尬', 'content': '火箭在客场以 113-115 惜败于鹈鹕, 4 连胜终结詹姆斯 - 哈登出战 34 分钟 16 投 5 中, 其中三分球 9 投只有 1 中, 罚球 14 罚 12 中, 拿到 23 分 11 助攻 5 篮板但也有 4 次失误, 其在场正负值为尴尬的 - 12 分', 'view_count': 7520, 'release_time': datetime.datetime(2018, 1, 27, 12, 5), 'author': 'youngcao', 'from': '腾讯体育','is_valibale': 1}, {'id': 4, 'type': '英超', 'title': '足总杯 - 曼联 4-0 英乙球队晋级 桑神首秀造两球', 'content': '2017-18 赛季英格兰足总杯第 4 轮, 曼联客场 4 比 0 击败英乙球队约维尔, 顺利晋级下一轮桑切斯迎来曼联首秀, 并制造了两个入球', 'view_count': 6560, 'release_time': datetime.datetime(2018, 1, 27, 5, 49), 'author': 'ricazhang', 'from': '腾讯体育','is_valibale': 1}, {'id': 5, 'type': '英超', 'title': '这才配红魔 7 号! 桑神首秀大腿级表演 回击嘘声质疑', 'content': '在今天凌晨对阵约维尔的首秀也值得期待虽然在登场的 72 分钟时间里没有进球, 但送出 1 次助攻且有有 6 次威胁传球的数据还是十分亮眼', 'view_count': 2760, 'release_time': datetime.datetime(2018, 1, 27, 6, 13), 'author': 'yaxinhao', 'from': '腾讯体育', 'is_valibale': 1}]
这里很巧妙的利用了 map 函数, 因为多条数据就可以进行迭代了, 需要操作每条数据, 这样就可以想到 map 函数
接下来我们再用面向对象的方法来用 python 进行查询数据库
1import pymysql 2class MysqlSearch(object): 3 def get_conn(self): 4 '''连接 mysql 数据库''' 5 try: 6 self.conn = pymysql.connect(host='127.0.0.1',user='root',passwd='your password',port=3306,charset='utf8',db='news') 7 except pymysql.Error as e: 8 print(e) 9 print('连接数据库失败')1011 def close_conn(self):12 '''关闭数据库'''13 try:14 if self.conn:15 self.conn.close()16 except pymysql.Error as e:17 print(e)18 print('关闭数据库失败')1920 def get_one(self):21 '''查询一条数据'''22 try:23 # 这个是连接数据库 24 self.get_conn()25 # 查询语句 26 sql = 'SELECT * FROM `new` WHERE `type`=%s'27 # 这个光标用来执行 sql 语句 28 cursor = self.conn.cursor()29 cursor.execute(sql,('英超',))30 new = cursor.fetchone()31 # 返回一个字典, 让用户可以按数据类型来获取数据 32 new_dict = dict(zip([x[0] for x in cursor.description],new))33 # 关闭 cursor34 cursor.close()35 self.close_conn()36 return new_dict37 except AttributeError as e:38 print(e)39 return None40 def get_all(self):41 '''获取所有结果'''42 sql = 'SELECT * FROM `new`'43 self.get_conn()44 try:45 cursor = self.conn.cursor()46 cursor.execute(sql)47 news = cursor.fetchall()48 # 将数据转为字典, 让用户根据键来查数据 49 news_list =list(map(lambda x:dict(zip([x[0] for x in cursor.description],[d for d in x])),news))50 # 这样也行, 连续用两个列表生成式 51 news_list = [dict(zip([x[0] for x in cursor.description],row)) for row in news]52 cursor.close()53 self.close_conn()54 return news_list55 except AttributeError as e:56 print(e)57 return None5859def main():60 # 获取一条数据 61 news = MysqlSearch()62 new = news.get_one()63 if new:64 print(new)65 else:66 print('操作失败')6768 # 获取多条数据 69 news = MysqlSearch()70 rest = news.get_all()71 if rest:72 print(rest)73 print(rest[7]['type'],rest[7]['title'])74 print('类型:{0}, 标题:{1}'.format(rest[12]['type'],rest[12]['title']))75 for row in rest:76 print(row)77 else:78 print('没有获取到数据')7980if __name__ == '__main__':81 main()
这样就可以通过实例的方法来进行查询数据库了
我们还可以根据页数来进行查询指定的数据数
1 def get_more(self,page,page_size): 2 '''查多少页的多少条数据''' 3 offset = (page-1)*page_size 4 sql = 'SELECT * FROM `new` LIMIT %s,%s' 5 try: 6 self.get_conn() 7 cursor = self.conn.cursor() 8 cursor.execute(sql,(offset,page_size,)) 9 news = [dict(zip([x[0] for x in cursor.description],new)) for new in cursor.fetchall()]10 cursor.close()11 self.close_conn()12 return news13 except AttributeError as e:14 print(e)15 return None1617def main():18 #获取某页的数据 19 news = MysqlSearch()20 new = news.get_more(3,5)21 if new:22 for row in new:23 print(row)24 else:25 print('获取数据失败')2627if __name__ == '__main__':28 main()
利用的是 mysql 的 limit 关键字, 还有其他的, 比如进行排序分组的感兴趣的可以自己尝试下
3
增加数据到数据库
1 def add_one(self): 2 sql = 'INSERT INTO `new`(`title`,`content`,`type`,`view_count`,`release_time`) VALUE(%s,%s,%s,%s,%s)' 3 try: 4 self.get_conn() 5 cursor = self.conn.cursor() 6 cursor.execute(sql, ('title', 'content', 'type', '1111', '2018-02-01')) 7 cursor.execute(sql, ('标题', '内容', '类型', '0000', '2018-02-01')) 8 # 一定需要提交事务, 要不不会显示, 只会占位在数据库 9 self.conn.commit()10 return 111 except AttributeError as e:12 print('Error:', e)13 return 014 except TypeError as e:15 print('Error:', e)16 # 发生错误还提交就是把执行正确的语句提交上去 17 # self.conn.commit()18 # 下面这个方法是发生异常就全部不能提交, 但语句执行成功的就会占位 19 self.conn.rollback()20 return 021 finally:22 cursor.close()23 self.close_conn()2425 def main():26 news = OperateSQL()27 if news.add_one():28 print('增加数据成功')29 else:30 print('发生异常, 请检查!!!')3132 if __name__ == '__main__':33 main()
因为是增加数据, 所以需要提交事务, 这就需要用到 conn .commit() 来进行提交, 在增加数据后, 如果不提交, 数据库就不会显示
还有修改数据和删除数据就不贴出来了, 只是把上面的 sql 变量的语句改成修改或者删除的语句就可以了, 如果你还不会, 建议练习下
END
代码我放在 github 了, 网站为 https://github.com/SergioJune/gongzhonghao_code, 有兴趣的可以去看看, 如果可以的话希望给个 star 哈!
这篇文章只适合入门的, 如果需要学习更多的话可以去查看 pymysql 的文档 http://pymysql.readthedocs.io/en/latest/
听说还有个福利: 放上某课的超多付费视频
链接: https://pan.baidu.com/s/1qYwSFiG
密码: 后台回复密码可见
MORE
来源: https://juejin.im/entry/5a9fb53d6fb9a028ba1f091a