CSV (Comma Separated Values) 格式是电子表格和数据库中最常见的输入、输出文件格式。在 RFC 4180规范推出的很多年前,CSV 格式就已经被开始使用了,由于当时并没有合理的标准,不同应用程序读写的数据会存在细微的差别。这种差别让处理多个来源的 CSV 文件变得困难。但尽管分隔符会变化,此类文件的大致格式是相似的,所以编写一个单独的模块以高效处理此类数据,将程序员从读写数据的繁琐细节中解放出来是有可能的。
csv模块定义的函数:
函数名 | 函数用途 |
---|---|
csv.reader(csvfile, dialect=‘excel’, **fmtparams) | 返回一个 reader 对象,该对象将逐行遍历 csvfile |
csv.writer(csvfile, dialect=‘excel’, **fmtparams) | 返回一个 writer 对象,该对象负责将用户的数据在给定的文件类对象上转换为带分隔符的字符串 |
csv.register_dialect(name[, dialect[, **fmtparams]]) | 将 name 与 dialect 关联起来。name 必须是字符串。 |
csv.unregister_dialect(name) | 从变种注册表中删除 name 对应的变种。 |
csv.get_dialect(name) | 返回 name 对应的变种。 |
csv.list_dialects() | 返回所有已注册变种的名称 |
csv.field_size_limit([new_limit]) | 返回解析器当前允许的最大字段大小 |
csv模块定义的类:
类名 | 类描述 |
---|---|
class csv.DictReader | 创建一个对象,其操作类似于常规 reader 但会将每行中的信息映射到一个 OrderedDict ,其中的键由可选的 fieldnames 形参给出。 |
class csv.DictWriter | 创建一个对象,该对象在操作上类似常规 writer,但能将字典映射到输出行 |
class csv.Dialect | Dialect 类是主要依赖于其属性的容器类,用于将定义好的参数传递给特定的 reader 或 writer 实例。 |
class csv.excel | excel 类定义了 Excel 生成的 CSV 文件的常规属性。它在变种注册表中的名称是 'excel' |
class csv.excel_tab | excel_tab 类定义了 Excel 生成的、制表符分隔的 CSV 文件的常规属性。它在变种注册表中的名称是 'excel-tab' 。 |
class csv.unix_dialect | unix_dialect 类定义了在 UNIX 系统上生成的 CSV 文件的常规属性,即使用 '\n' 作为换行符,且所有字段都有引号包围。 |
class csv.Sniffer | Sniffer 类用于推断 CSV 文件的格式。 |
csv模块定义了以下常量:
csv.QUOTE_ALL | 指示 writer 对象给所有字段加上引号 |
csv.QUOTE_MINIMAL | 指示 writer 对象仅为包含特殊字符(例如 定界符、引号字符 或 行结束符 中的任何字符)的字段加上引号。 |
csv.QUOTE_NONNUMERIC | 指示 writer 对象为所有非数字字段加上引号。 |
csv.QUOTE_NONE | 指示 writer 对象不使用引号引出字段。 |
csv模块定义了以下异常:
exception csv.Error
该异常可能由任何发生错误的函数抛出。
代码:
import csv
import pymysql
# 创建mysql连接
conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='abc123',db='zqs')
cursor = conn.cursor()
sql1 = "select empno,ename , mgr,hiredate from emp where 1 = 1"
headers = ["empno","ename","mgr","hiredate"]
cursor.execute(sql1)
rows = cursor.fetchall()
with open('E:\python\emp.csv', 'w', newline='') as csvfile:
my_csv_write = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
my_csv_write.writerow(headers)
my_csv_write.writerows(rows)
conn.commit()
# 关闭连接
cursor.close()
conn.close()
测试记录:
如下查看可得知,数值、字符、日期以及空值都正常导出到了csv文件
对于CSV中空值的处理
数值型空值,必须是 %s 而不能使用 ‘%s’
字符型空值以及时间类型空值,必须是 %s 而不能使用 ‘%s’,但是录入其它非空的字符,又必须用’%s’
从上图可以看到 ename列是字符型空值,mgr、comm列是数值型空值,hiredate是日期型空值
Python代码:
db_setting.py
# 存储数据库信息
# 创建一个列表嵌套列表,存储数据库信息
# 依次是 数据库备注、ip、端口、、用户名、密码、登陆数据库名
mysql_msg = [['本地mysql', 'localhost', 3306 , 'root', 'abc123', 'zqs'],
['远程mysql', '10.31.1.123', 3306, 'root', 'abc123', 'test']
]
mysql_test3.py
import pymysql, datetime
import csv
import db_setting
import math
from numpy import nan as NaN
class mysql_class(object):
"""对mysql的操作创建一个类"""
def __init__(self, name):
self.name = name
def login_mysql(self):
"""获取mysql的登陆信息"""
mysql_msg = db_setting.mysql_msg
name = self.name
for i in range(0,len(mysql_msg) ):
exec_db = mysql_msg[i]
if name == exec_db[0]:
# 根据输入连接数据库
return exec_db
# conn = pymysql.connect(host=exec_db[1], port=exec_db[2], user=exec_db[3], passwd=exec_db[4],db=exec_db[5])
else:
pass
def csv_insert_mysql(self):
"""将csv的文件录入到mysql"""
exec_db = mysql_class.login_mysql(self)
conn = pymysql.connect(host=exec_db[1], port=exec_db[2], user=exec_db[3], passwd=exec_db[4], db=exec_db[5] ,charset='utf8')
cursor = conn.cursor()
# 测试了数值类型还是会存在问题, yyyy/mm/dd 这类时间格式测试了也不会有问题的
# 数值型空值,必须是 %s 而不能使用 '%s'
# 字符型空值以及时间类型空值,必须是 %s 而不能使用 '%s',但是录入其它非空的字符,又必须用'%s'
sql = ""
sql1 = "insert into emp_csv(empno, ename, job, mgr, hiredate, sal, comm, deptno) values ('%s', %s, '%s', %s, '%s', '%s', %s, '%s') "
sql2 = "insert into emp_csv(empno, ename, job, mgr, hiredate, sal, comm, deptno) values ('%s', '%s', '%s', %s, '%s', '%s', %s, '%s') "
sql3 = "insert into emp_csv(empno, ename, job, mgr, hiredate, sal, comm, deptno) values ('%s', '%s', '%s', %s, %s, '%s', %s, '%s') "
filename = 'E:/python/file_test/emp_csv_2.csv'
with open(filename, 'r') as f:
reader = csv.reader(f)
# print(type(reader))
for i, row in enumerate(reader):
# 剔除第一行的列头
if i > 0:
empno = row[0]
if row[1]:
ename = row[1]
else:
ename = 'NULL'
job = row[2]
if row[3]:
mgr = row[3]
else:
mgr = 'NULL'
if row[4]:
hiredate = row[4]
else:
hiredate = 'NULL'
sal = row[5]
if row[6]:
comm = row[6]
else:
comm = 'NULL'
deptno = row[7]
print(empno, ename, job, mgr , hiredate, sal, comm , deptno)
# 遍历列表,循环录入数据
if not row[1]:
sql = sql1
if not row[4]:
sql = sql3
# 如果存在两列同时为null的情况,还得继续增加判断条件
if row[1]:
if row[4]:
sql = sql2
cursor.execute(sql % (empno, ename, job, mgr, hiredate, sal, comm, deptno))
conn.commit()
# 关闭连接
cursor.close()
conn.close()
if __name__ == '__main__':
my_class1 = mysql_class('本地mysql')
my_class1.csv_insert_mysql()
1.https://docs.python.org/zh-cn/3.6/library/csv.html#