今天来测试一个案例,将csv文件导入到mysql(mariadb)数据库中。
最后成功的代码托管在:python/load_csv_into_mysql.py at main · laufei90/python (github.com) 。
这一次纠结了好久,下面的两个问题都是with语句的上下文管理器造成的。上下文管理器在对打开资源、处理资源、最后关闭资源的场景有用,可以有效减少代码的数量,使得逻辑更加清除。但是上下文管理器返回一个对象,该对象必须有__enter__ 和 __exit__方法,如果使用有问题,就需要进入源码来查看了。
1、with conn as cur ,使用上下文管理器来管理cursor时,一直提示“AttributeError: 'Connection' object has no attribute 'execute'” ,根据说明信息Connection类没有execute方法,可是按照介绍的说明,with语句的表达式会返回一个cursor,而不是Connection类。于是笔者进去pymysql包的connections.py中查看,发现源码里面并不是return self.cursor() ,而是return self ,即with语句的表达式还是会返回一个Connection类。估计是版本问题,新版本已经取消。于是笔者直接改写成:with conn.cursor() as cur 后测试成功。
2、使用上下文管理器来管理Connection类时,发现插入到数据库的条目,在insert后可以select打印处理,但是数据库里面没有看到插入的数据。比较一猜就是没有自动commit!可是按照介绍的说明,with语句的表达式可以自动提交啊。于是笔者进去pymysql包的connections.py中查看,发现enter里面没有自动提交的功能了,而且exit里面也没有rollback的功能。那么就只能自己在execute后自己conn.commit ,或者自己设置conn.autocommit(1) ,或者在connections.py将autocommit=Falise改为True 。如果需要的话可以选择try + except来完成commit和roolback 。
最后来看一下csv文件导入到mysql数据库的功能。csv文件是个纯文本形式存储数据表格,在linux中可以使用cat打开。python的标准库的csv模块可以完成csv格式的数据读写问题。
下面是显现的方法,回头一看,有时不用为了with语句而硬套,简单的其实是最高效的,今晚花了三个实在有点浪费。下面看看定义的函数。
1、get_data函数打开文件csv文件, 通过open方法打开文件(python文件实现了迭代器协议),然后使用with语句来迭代读取csv文件,然后存入命名元组,可以使用列名作为下标访问元组中的内容。
2、execute_sql,使用上下文管理器包装execute执行语句,做到DRY 。
3、main主函数,连接数据库,执行SQL语句,提交commit,关闭连接。
网友评论