关于 Excel 拼接 sql 这个操作, 我已经整过好几篇了, 当然在工作中也是蛮常用的, 今天主要是来写个终篇, 彻底结束它, 然后将代码进行打包为 exe 这样的桌面小软件, 除了自己用, 也可以分享给需要的小伙伴用, 不用装环境也可以运行. 还是先对这一系列做一个汇总吧.
-
Excel 批量导入mysql(创建表-追加数据): https://www.cnblogs.com/chenjieyouge/p/11811784.html
-
Excel 逐条导入Mysql(数据更新): https://www.cnblogs.com/chenjieyouge/p/11812126.html
-
Excel 数据拼接为 insert 语句脚本: https://www.cnblogs.com/chenjieyouge/p/12643006.html
最后新新增, 自动生成 create table 语句, 然后再将功能给打个包, 自己用呀.
完整代码
不多哔哔, 直接上代码, 刚写的, 自己试了几把, 感觉还是比较香的哦, 我用的是 window 哈.
"""
功能: Excel 文件拼接为sql脚本
输入: 一个Excel 的文件路径
输出: 一个sql文件, 包含自动生成的 create_table 语句 和 insert 数据的语句
"""
import pandas as pd
def Excel_to_sql_file(file_path, output_path="D:/"):
"""将Excel 转为Sql文件,并存储在 \'D:/\'下"""
df = pd.read_excel(file_path)
# 获取表名, 字段名
file_suffix = file_path.split("/")[-1]
tb_name = file_suffix[:file_suffix.rfind(\'.\')]
col_lst = df.columns
with open(output_path + tb_name + ".sql", \'w\', encoding=\'utf8\') as f:
# 先写入建表的 sql
f.write(f\'drop table if exists {tb_name};\\n\')
f.write(f\'create table {tb_name}(\')
f.write(\'\\n\\n\\t\')
# 最后一个字段要单独处理, 没有逗号 ",", 于是可用 *的方式(pakage) 来代替切片
*head_lst, end = col_lst
for col in head_lst:
# name varchar(200),
f.write(f\'{col} varchar(200), \\n\\t\')
f.write(f\'{end} varchar(200)\')
f.write(\'\\n);\')
# 提示检查 create table 的部分
f.write(f\'\\n\\n-- 先要检查建表语句是否正确哦, 比如字段中有"空格", "-" 都是不行的\')
# 将 Excel 每行数据拼接为 insert into table values (....); 的脚本
f.write("\\n\\n\\n\\n")
for _, val in df.iterrows():
# 将每行值, 每个元素都转为 str, 整体也套为 str
val_str = str([str(i) for i in val.values])
# 通过切片, 将 "[\'a\', \'b\']" => "\'a\', \'b\'" => 再来 eval 就ok了
sql_value = eval(val_str[1:-1])
f.write(f\'insert into {tb_name} values {sql_value};\' + \'\\n\')
print("转换完成! 存在您的 D盘目录下, 快去查看吧!")
if __name__ == \'__main__\':
file = "D:/test_data/超市数据20.xls"
Excel_to_sql_file(file)
效果演示
数据还是以当时练习 Tableau 的超市数据集为例, 中文版本的呀.
然后呢, 转为SQL脚本文件, 打开是这样的, 前面是建表的 create table ..的 DDL 语句, 后面的数据的 insert 语句.
最后在 sql 终端中执行这个脚本即可, 我用的是 mysql, 可以用 source 文件路径.sql 这个命令来执行这个脚本.
source D:/超市数据20.sql
不过中文名似乎有点 小问题, 改为英文名就正常了.
如果, 还是不知道如何执行 sql 脚本, 那, 也可以用记事本打开, 然后 Ctr + A 全选, 然后复制贴到 终端也是ok 的, 我喜欢这样, 简单粗暴, 不用管啥快慢性能之类的.
打包为 exe
虽然功能简单, 但, 还是封装为一个小 gui 程序比较好. 虽然我更喜欢用 代码的方式, 但万一哪天, 没有环境了, 或者给别人用, 就不太好了, 就打了个包, 用的是 Python 自带的 tkinter 库, 我感觉用起来还是蛮不错的哦. 打包用的是
pyinstaller 这个兄弟, 还是很好用的.
小技巧是, 单独弄一个纯净的虚拟环境来打包, 虚拟环境, 用 Python 自带的行, 原装的才是最好的.
创建: 在你想创建的目录下, 终端执行: python -m venv 虚拟环境名称
进入: cd 到 Scripts 路径下, 终端执行: activate.bat 即进入虚拟环境
然后切换到要 打包的 main.py 文件下, 打包即可.
打包命令: pyinstaller -F -w xxx.py
完整代码 (GUI版)
要打包了, 就大量清掉注释呀, 这样也节省内存和提高性能.
import tkinter as tk
from tkinter import filedialog, messagebox
import pandas as pd
# 主窗口
root = tk.Tk()
root.title("Excel 拼接为 SQL 脚本")
root.minsize(350, 100)
root.resizable(0, 0)
def excel_to_sql_file():
file_path = tk.filedialog.askopenfilename(title="读取文件")
messagebox.showinfo("您选择的Excel是:", file_path)
try:
df = pd.read_excel(file_path)
# 获取表名, 字段名
file_suffix = file_path.split("/")[-1]
tb_name = file_suffix[:file_suffix.rfind(\'.\')]
col_lst = df.columns
except Exception as e:
messagebox.showerror("Excel异常", e)
with open("D:/" + tb_name + ".sql", \'w\', encoding=\'utf8\') as f:
# 先写入建表的 sql
f.write(f\'drop table if exists {tb_name};\\n\')
f.write(f\'create table {tb_name}(\')
f.write(\'\\n\\n\\t\')
*head_lst, end = col_lst
for col in head_lst:
f.write(f\'{col} varchar(200), \\n\\t\')
f.write(f\'{end} varchar(200)\')
f.write(\'\\n);\')
f.write(f\'\\n\\n-- 先要检查建表语句是否正确哦, 比如字段中有"空格", "-" 都是不行的\')
# 拼接 insert 语句
f.write("\\n\\n\\n\\n")
for _, val in df.iterrows():
val_str = str([str(i) for i in val.values])
sql_value = eval(val_str[1:-1])
f.write(f\'insert into {tb_name} values {sql_value};\' + \'\\n\')
messagebox.showinfo("转换成功", "已存在您的 D盘目录下, 快去查看吧!")
l_file = tk.Label(root, text="我将是要对 Excel 文件进行 : ")
l_file.place(relx=0.03, rely=0.4)
b_file = tk.Button(root, text="选择并拼接为SQL", command=excel_to_sql_file)
b_file.place(relx=0.6, rely=0.38)
if __name__ == \'__main__\':
root.mainloop()
然后运行运行完即可.
小结
- Excel 转 SQL, 或者直接存 数据库.... 这些操作已经玩透了, 以后再也不玩了, 没意思了.
- 现多养成将一些小功能代码, 写为 GUI 然后打个 exe, 这样还能分享给小伙伴用.
- 多用内置的库, 原装的才是最好的, 然后多抄代码, 抄多了,自然就会写了, 比如, *lst 这类的组包, 操作, 之前只会用切片, 现在都会用组包了, 还是有点高级和优雅的.