博主工做长期需使用到数据库查询数据,于是接触到了数据库的一些皮毛知识。可是数据库和办公网不能互通,远端访问也无法实现,因此长期以来查询数据都至关麻烦。近期博主在本身的工做电脑上搭建了一个的MySQL数据库,并尝试导入一些数据进去,顺便本身查询,其中遇到了各类各样的问题,才深入领悟到后端操做的艰难,写篇博客记录一下其中的艰难过程。前端
注:如下内容,仅供用于学习交流,并且博主也对相关内容进行的打码处理,文件名和数据库名都是用的XXX来表示的。python
博主的数据库是用的MySQL,用的是CMD命令行方式安装和配置的,网上有不少教程,可是参差不齐,有空了我专门写一篇博客记录安装过程,这边博客就不说了。不过在安装时,必定要牢记系统给你默认设置的链接密码,若是没记住的话,会让你崩溃,网上教程一堆,能实际解决问题的没两个,这个密码是关键,切记、切记。web
博主用的是Navicat premium 15,界面以下:
为何须要这个软件呢,这个软件可让你方便的链接你的数据库,也能够在里面写一些查询语句,甚至能够将数据导入到数据库,并且还支持批量导入,总之,很是方便,能够理解为数据库的前端操做软件。但实际使用过程却没有那么友好,好比我导入数据到个人数据库时,常常出现下面的问题:
finished with error
也不告诉你那里出了错,反正就是数据不全,大概只导入了1/4的数据。固然也不是全部的数据导入都会出现这个问题,可是确实头疼,博主网上搜了一堆教程没一个能解释明白的,因此才有了后面用Python导入数据库的尝试。不过用Navicat写查询语句确实方便,你的数据库须要这么个数据库可视化软件,否则你操做数据库,就永远像个黑客同样在CMD里写命令行来操做了。sql
博主这边有不少txt文件,但都是同一批字段的数据,至于为何会这样,博主也懒得解释。反正如今的工做是,把这些txt文件合并到一个文件里去,这样导入数据库也方便点不是吗?
固然你也能够本身在excel里面一个个的复制粘贴,可是感受一是工做量太大,十来个文件还好,几百个文件你要这么操做,能让人抓狂,并且逼格也过低了,如今流行自动化办公。
直接上代码:数据库
# -*- coding: utf-8 -*- """ Created on Tue Jul 14 15:25:44 2020 @author: HP """ #合并一个文件夹下的多个txt文件 #coding=utf-8 import os import pandas as pd #获取目标文件夹的路径 filedir = r'C:\xxx\xxx' #获取当前文件夹中的文件名称列表 filenames=os.listdir(filedir) i=0 data = pd.read_csv(r'C:\xxx\xxx\xxx.txt',sep = '\t') col = list(data) data = pd.DataFrame(columns=col) #先遍历文件名 for filename in filenames: i+=1 print(i) if i>0: filepath = filedir+'\\'+filename print(filepath) #遍历单个文件,读取行数 # datai = pd.read_csv(filepath, sep='\t', dtype=str) datai = pd.read_csv(filepath, sep='\t', converters={ 'item': str}) data = data.append(datai) ''' for line in open(filepath, 'r', encoding='utf-8-sig', errors='ignore'): # print(str(line)) f.writelines(line) # f.write('\n') ''' #关闭文件 # f.close() data.to_excel('XXX.xlsx', index=False)
来解释一下代码
filedir = r’C:\xxx\xxx’ 我把全部的文件放在这个文件夹里,注意是一个绝对的路径
filenames=os.listdir(filedir) 获取这个文件夹里面全部的文件列表后端
data = pd.read_csv(r'D:\xxx\xxx.txt',sep = '\t') col = list(data) data = pd.DataFrame(columns=col)
这里几行代码呢,目的是建立一个空的dataframe,这个空的dataframe的列就是上面那个文件夹里面某个文件的列名
后面就是写循环,往列表里面添加数据,而后将列表转换为excel文件了。服务器
''' for line in open(filepath, 'r', encoding='utf-8-sig', errors='ignore'): # print(str(line)) f.writelines(line) # f.write('\n') '''
博主注释起来的这块代码,是写入txt的方式,看需求,固然,这里f没定义,能够在循环外面定义一下f,好比:网络
# f=open('result.txt','w')
直接上代码了再解释吧app
# -*- coding: utf-8 -*- """ Created on Tue Jul 14 17:34:23 2020 @author: HP """ """ 功能:将Excel数据导入到MySQL数据库 """ import xlrd import MySQLdb import pandas as pd d = pd.read_csv('xxx.txt',sep = '\t') col = list(d) cols = ','.join(col) # Open the workbook and define the worksheet book = xlrd.open_workbook("XXX.xlsx") # excel文件名 # book = xlrd.open_workbook("1.xlsx") sheet = book.sheet_by_index(0) # excel文件中的sheet名 # 创建一个MySQL链接 database = MySQLdb.connect(host="xxxxxxx", user="xxxx", passwd="xxxxxx", db="xxxxx", charset="utf8") # 得到游标对象, 用于逐行遍历数据库数据 cursor = database.cursor() # 建立插入SQL语句 # query = """INSERT INTO acd_file (%s) VALUES (%s)""" %(cols, ss) # 建立一个for循环迭代读取xls文件每行数据的, 从第二行开始是要跳过标题 data_list = [] for r in range(1, sheet.nrows): row_list = [] for t in range(len(col)): value_rt = sheet.cell(r,t).value type_rt = sheet.cell(r,t).ctype if type_rt == 2: value_rt = str(int(value_rt)) row_list.append(value_rt) data_list.append(row_list) # values = ','.join(data_list) # query = """INSERT INTO acd_file (%s) VALUES (%s)""" %(cols, s) # 执行sql语句 # cursor.execute(query, values) val = '' for i in range(0, len(col)): val = val + '%s,' result =cursor.executemany("insert into xxx (%s) values(" %(cols) + val[:-1] + ")", data_list) print(result) # 关闭游标 cursor.close() # 提交 database.commit() # 关闭数据库链接 database.close() # 打印结果 print("") print("Done! ") print("") columns = str(sheet.ncols) rows = str(sheet.nrows) print("我刚导入了 ", columns, " 列 and ", rows, " 行数据到MySQL!")
真的挺复杂,也不知道博主能不能讲明白,我挑一些本身认为比较晦涩的代码来解释吧svg
d = pd.read_csv('xxx.txt',sep = '\t') col = list(d) cols = ','.join(col)
这里主要是把文件的列名变成一串字符串,join函数能够将列表转化为字符串,分割符号是’,'这个逗号
# Open the workbook and define the worksheet book = xlrd.open_workbook("XXX.xlsx") # excel文件名 # book = xlrd.open_workbook("1.xlsx") sheet = book.sheet_by_index(0) # excel文件中的sheet名
把上面合并的那个excel文件读进来,而且获取这个excel的sheet名,从上面批量合并数据文件这一步来看,博主其实只有一个sheet。
database = MySQLdb.connect(host="xxxxxxx", user="xxxx", passwd="xxxxxx", db="xxxxx", charset="utf8")
这行代码很是关键,关系到你可否把数据写到数据库里去,connect函数就是用来连接数据库的,里面的参数我来解释一下:
data_list = [] for r in range(1, sheet.nrows): row_list = [] for t in range(len(col)): value_rt = sheet.cell(r,t).value type_rt = sheet.cell(r,t).ctype if type_rt == 2: value_rt = str(int(value_rt)) row_list.append(value_rt) data_list.append(row_list)
这段代码的目的是将表中全部的数据所有取出来,并写入到data_list这个列表中
type_rt = sheet.cell(r,t).ctype用于获取每一个字符的类型
ctype : 0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error
我将全部数字型的数据所有转换为字符串,便于完整的写入数据,至于到哪里去把字符串修改回来,这个能够到Navicat里面去设置。固然,这不是最佳的数据处理方式,只是比较适合博主的数据而已
val = '' for i in range(0, len(col)): val = val + '%s,' result =cursor.executemany("insert into xxx (%s) values(" %(cols) + val[:-1] + ")", data_list)
变量val用来生成一串’%s’这个玩意儿,val[:-1]用切片切掉最后一个逗号,其实这里有更简单的写法,像前面同样用join函数
s =['%s']*len(col) ss = ','.join(s)
这里的ss和val[:-1]是等价的。
executemany是批量写入函数,“insert into xxx (%s) values(” %(cols) + val[:-1] + ")"中的xxx是数据表。还有另一种写法,不用批量导入,而是用execute函数,每读一行,就写一行,写在循环里面,可是当时总是报错,我就没继续下去了。
后面就是常规的数据库操做了
固然,整个过程不断的报错,好比报错说个人字符串长度太长了,等等,要在数据库里面修改一些参数,可能每一个人遇到的问题不同,遇到了就去网上搜索教程,基本都能解决。
至此完成了数据的写入,接下来看看怎么在Python里查询数据
仍是先上代码
# -*- coding: utf-8 -*- """ Created on Thu Jul 16 09:33:42 2020 @author: HP """ import MySQLdb import pandas as pd conn = MySQLdb.connect( host="xxxx", user="xxxx", passwd="xxxxx", db="xxxxx", charset="utf8") cur = conn.cursor() query = """ select x1, x2, x3, x4 from table1 where x1 >= 1 and x1 < 100 """ cur.execute(query) result = cur.fetchall() df_result = pd.DataFrame(list(result), columns=['x1','x2','x3','x4'])
第一步,连接数据库并登录
第二步,写查询语句,select from where基本查询语法
第三步,执行查询语句
顺利出结果
相对来讲,要简单的多
从博主决定搭建数据库到最后打通数据库,整体来讲,感受很费劲,也走了不少弯路,给个人感受就是后端的东西要比前端复杂一点,固然,博主水平有限,也就目前的认知水平这样,前端的东西其实也很复杂,只是我我的接触的相对多一点而已。 不过仍是很开心的,毕竟又get了个新技能。