让Python帮你搞定MySQL数据库
MySQL是常用的数据库之一,也是面试工作必备技能之一。
本文通过一个实战,将Python与SQL语句结合起来使用,搞定MySQL数据库。
我们在github上下载fifa18球员数据,将这些信息存入到mysql。 ①数据下载地址: https://github.com/amanthedorkknight/fifa18-all-player-statistics ②选择:Complete->basicplayerdata.csv
#创建公司数据库,编码格式utf-8
CREATE DATABASE fifa18_db DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
#选择数据库:
use fifa18_db;
#创建球员表:id,名称,海报地址,俱乐部,年龄,薪资等,与csv文件对应
create table player(id int Primary key auto_increment,
player_id int, name char(64), age int, poster char(64),
flag char(64), overall int, potential int, club char(64) default '', club_Logo char(64),
value char(16), wage char(16), special int) default charset =utf8;
path = '/home/linux/workdir/data/basicplayerdata.csv'
#字段名称
field = ['','ID','Name','Age','Photo','Nationality','Flag','Overall','Potential','Club','Club Logo','Value','Wage','Special']
f = open(path)
fcsv = csv.DictReader(f, fieldnames = field)
#第一行去掉
line = next(fcsv)
#第一行有效数据
line = next(fcsv)
print(line)
OrderedDict([('', '0'), ('ID', '158023'), ('Name', 'L. Messi'), ('Age', '30'),
('Photo', 'https://cdn.sofifa.org/players/4/18/158023.png'), ('Nationality', 'Argentina'),
('Flag', 'https://cdn.sofifa.org/flags/52.png'),
('Overall', '94'), ('Potential', '94'), ('Club', 'FC Barcelona'),
('Club Logo', 'https://cdn.sofifa.org/teams/2/18/light/241.png'),
('Value', '€118.5M'), ('Wage', '€565K'), ('Special', '2161')])
sqlfield = ['player_id','name','age','poster','nationality','flag','overall','potential','club','club_logo','value','wage','special']
csvfield = ['ID','Name','Age','Photo','Nationality','Flag','Overall','Potential','Club','Club Logo','Value','Wage','Special']
#转成字典:
keysinfo = dict(zip(sqlfield, csvfield))
#填充数据:
data = {}
for sfield, cfield in keysinfo.items():
ele = line.get(cfield, '')
data.setdefault(sfield, ele)
print(data)
{'player_id': '158023', 'name': 'L. Messi', 'age': '30', 'poster': 'https://cdn.sofifa.org/players/4/18/158023.png',
'nationality': 'Argentina', 'flag': 'https://cdn.sofifa.org/flags/52.png',
'overall': '94', 'potential': '94', 'club': 'FC Barcelona',
'club_logo': 'https://cdn.sofifa.org/teams/2/18/light/241.png',
'value': '€118.5M', 'wage': '€565K', 'special': '2161'}
tablename = 'player'
keys = data.keys()
fields = ','.join(keys)
vals = ','.join(["'%s'"% val for val in data.values()])
sql = f"INSERT INTO {tablename}({fields}) VALUES({vals})"
print(sql)
INSERT INTO player(player_id,name,age,poster,nationality,flag,overall,potential,club,club_logo,value,wage,special)
VALUES('158023','L. Messi','30','https://cdn.sofifa.org/players/4/18/158023.png','Argentina','https://cdn.sofifa.org/flags/52.png','94','94','FC Barcelona','https://cdn.sofifa.org/teams/2/18/light/241.png','€118.5M','€565K','2161')
#编码格式:utf-8
db = pymysql.connect("localhost","root","abc123","fifa18_db", charset='utf8')
#获取游标
cursor = db.cursor()
cursor.execute(sql)
#提交数据
db.commit()
#断开连接
cursor.close()
db.close()
import csv
import pymysql
class LoadDataFromCsvToMysql:
def __init__(self, csvpath, csvfield, mysqlfield, table, sqlconfig):
#初始化参数
pass
def connectSql(self):
#连接数据库,获取游标
pass
def disconnectSql(self):
#断开数据库,获取游标
pass
def processSql(self, sql):
#处理sql语句
pass
def loadCsv(self):
#打开csv文件,返回csv对象
pass
def closeCsv(self):
#关闭csv文件
pass
def gensql(self, linedata):
#生成sql语句
pass
def process(self):
#对外接口,打开文件并写数据库
pass
import csv
import pymysql
class LoadDataFromCsvToMysql:
def __init__(self, csvpath, csvfield, mysqlfield, table, sqlconfig):
#初始化参数
self.dbconfig = sqlconfig
self.inpath = csvpath
self.sqlfield = mysqlfield
self.csvfield = csvfield
self.fieldmap = dict(zip(mysqlfield, csvfield[1:]))
self.tablename = table
def connectSql(self):
self.db = pymysql.connect(**self.dbconfig, charset='utf8')
self.cursor = self.db.cursor()
def disconnectSql(self):
self.cursor.close()
self.db.close()
def processSql(self, sql):
ret = self.cursor.execute(sql)
self.db.commit()
return ret
def loadCsv(self):
#打开csv文件
self.f = open(path)
fcsv = csv.DictReader(self.f, fieldnames = self.csvfield)
next(fcsv)
return fcsv
def closeCsv(self):
self.f.close()
def gensql(self, linedata):
pass
def process(self):
#测试数据库与csv文件打开关闭
self.connectSql()
print('connect sql...')
fcsv = self.loadCsv()
self.disconnectSql()
self.closeCsv()
print('disconnect sql') path = '/home/linux/workdir/data/basicplayerdata.csv'
sqlfield= ['player_id','name','age','poster','nationality','flag','overall','potential','club','club_logo','value','wage','special']
csvfield = ['','ID','Name','Age','Photo','Nationality','Flag','Overall','Potential','Club','Club Logo','Value','Wage','Special']
dbconfig = {'host':'localhost','port':3306,'user':'root','passwd':'abc123','db':'fifa18_db'}
obj = LoadDataFromCsvToMysql(path, csvfield, sqlfield, 'player', dbconfig)
obj.process()
connect sql...
load csvfile
disconnect sql
def process(self):
#测试数据库与csv文件打开关闭
self.connectSql()
print('connect sql...')
fcsv = self.loadCsv()
for line in fcsv:
sql = self.gensql(line)
print(sql)
n = self.processSql(sql)
self.disconnectSql()
self.closeCsv()
print('disconnect sql')
def gensql(self, linedata):
#产生sql语句
data = {}
for sfield, cfield in self.fieldmap.items():
ele = linedata.get(cfield, '')
data.setdefault(sfield, ele)
tablename = self.tablename
keys = data.keys()
fields = ','.join(keys)
vals = ','.join(["'%s'"% val for val in data.values()])
sql = f"INSERT INTO {tablename}({fields}) VALUES({vals})"
return sql
"('158023','L. Messi','30','https://cdn.sofifa.org/players/4/18/158023.png',..)"
def gensql(self, linedata):
#产生sql语句
data = {}
for sfield, cfield in self.fieldmap.items():
ele = linedata.get(cfield, '')
data.setdefault(sfield, ele)
tablename = self.tablename
keys = data.keys()
fields = ','.join(keys)
vals = ','.join(['"%s"'% val for val in data.values()])
sql = f'INSERT INTO {tablename}({fields}) VALUES({vals})'
return sql
dstram","18","https://cdn.sofifa.org/players/4/18/238813.png","England","https://cdn.sofifa.org/flags/14.png","47","65","Crewe Alexandra","https://cdn.sofifa.org/teams/2/18/light/121.png","€60K","€1K","1305")
INSERT INTO player(player_id,name,age,poster,nationality,flag,overall,potential,club,club_logo,value,wage,special)
VALUES("238306","A. Conway","19","https://cdn.sofifa.org/players/4/18/238306.png","Republic of Ireland","https://cdn.sofifa.org/flags/25.png","47","63","Galway United","https://cdn.sofifa.org/teams/2/18/light/1571.png","€60K","€1K","1314")
disconnect sql
1555235373.5942054 1555235392.2122808
①sql中查询数据我们步骤:连接数据库,执行sql语句,关闭数据库; ②查询与写入很多方法通用,考虑继承LoadDataFromCsvToMysql类; ③需要重载init,process,processSql方法;
class QueryMysql(LoadDataFromCsvToMysql):
def __init__(self, sqlconfig):
#调用父类方法,初始化传一些无效参数
super(QueryMysql, self).__init__('',[], [], '', dbconfig)
def genSql(self, table, fields, condition=None):
#查询语句生成
fds = ','.join(fields)
cond = ''
print(condition)
if condition:
cond = f' where {condition}'
sql = f'select {fds} from {table}{cond}'
return sql
def process(self, tablename, fields, condition=None):
#对外接口
#调用父类中的连接数据库,关闭数据库方法
self.connectSql()
sql = self.genSql(tablename, fields, condition)
self.processSql(sql)
items = self.cursor.fetchall()
for item in items:
print(item)
print('all Argentina player:', len(items))
self.disconnectSql() dbconfig= {'host':'localhost','port':3306,'user':'root','passwd':'abc123','db':'fifa18_db'}
tablename = 'player'
files = ['name','poster', 'age']
obj = QueryMysql(dbconfig)
cond = 'nationality="Argentina"'
obj.process(tablename, files, cond)
('L. Messi', 'https://cdn.sofifa.org/players/4/18/158023.png', 30)
('G. Higuaín', 'https://cdn.sofifa.org/players/4/18/167664.png', 29)
('P. Dybala', 'https://cdn.sofifa.org/players/4/18/211110.png', 23)...('A. Miño', 'https://cdn.sofifa.org/players/4/18/243298.png', 23)
('T. Durso', 'https://cdn.sofifa.org/players/4/18/240955.png', 18)
('K. Humeler', 'https://cdn.sofifa.org/players/4/18/240291.png', 20)
('J. Mendive', 'https://cdn.sofifa.org/players/4/18/241584.png', 20)
all Argentina player: 966
相关阅读: