最近經常要將數據導入到mysql中,我寫過一次後也是複製粘貼前面寫過的,但老是經常忘記寫過的放哪去了,索性整理下直接寫到博客裏面來
方法:
1、使用 pymysql 庫, 數據一條條插入,或者用Django ORM裏面的方法,數據批量插入
2、使用 pandas 庫,一次性插入,也可批量插入
3、使用 pyspark, 一次性插入(可以不用建表,但是表沒有註釋, 即 mysql 的 COMMENT,要註釋的話可以建空表)
方法1:
mysql 首先創建表
CREATE TABLE `data_to_mysql` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`sex` VARCHAR(20) DEFAULT NULL COMMENT '性別',
`age` int(5) DEFAULT NULL COMMENT '年齡',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='數據導入mysql';
import pymysql
import pandas as pd
mysql_host = 'localhost'
mysql_db = 'test'
mysql_user = 'root'
mysql_pwd = '123456'
mysql_table = 'data_to_mysql'
class MYSQL:
def __init__(self):
# MySQL
self.MYSQL_HOST = mysql_host
self.MYSQL_DB = mysql_db
self.MYSQ_USER = mysql_user
self.MYSQL_PWD = mysql_pwd
self.connect = pymysql.connect(
host=self.MYSQL_HOST,
db=self.MYSQL_DB,
port=3306,
user=self.MYSQ_USER,
passwd=self.MYSQL_PWD,
charset='utf8',
use_unicode=False
)
print(self.connect)
self.cursor = self.connect.cursor()
def insert_mysql(self, data_json):
"""
數據插入mysql
:param data_json:
:return:
"""
sql = "insert into {}(`name`, `sex`, `age`) VALUES (%s, %s, %s)".format(mysql_table)
try:
self.cursor.execute(sql, (data_json['name'], data_json['sex'], data_json['age']))
self.connect.commit()
print('數據插入成功')
except Exception as e:
print('e= ', e)
print('數據插入錯誤')
def main():
mysql = MYSQL()
df = pd.DataFrame({
'name': ['戴沐白','奧斯卡','唐三','小舞','馬紅俊','寧榮榮','朱竹清'],
'sex': ['男', '男', '男', '女', '男', '女', '女'],
'age': [23, 22, 21, 100000, 20, 20 ,20]
})
# orient='records', 表示將DataFrame的數據轉換成我想要的json格式
data_json = df.to_dict(orient='records')
for dt in data_json:
mysql.insert_mysql(dt)
if __name__ == '__main__':
main()
方法2
mysql 首先創建表
CREATE TABLE `data_to_mysql` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`sex` VARCHAR(20) DEFAULT NULL COMMENT '性別',
`age` int(5) DEFAULT NULL COMMENT '年齡',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='數據導入mysql';
import pandas as pd
from sqlalchemy import create_engine
mysql_host = 'localhost'
mysql_db = 'test'
mysql_user = 'root'
mysql_pwd = '123456'
mysql_table = 'data_to_mysql'
def main():
engine = create_engine('mysql+pymysql://{}:{}@{}:3306/{}?charset=utf8'.format(mysql_user, mysql_pwd, mysql_host, mysql_db))
df = pd.DataFrame({
'name': ['戴沐白','奧斯卡','唐三','小舞','馬紅俊','寧榮榮','朱竹清'],
'sex': ['男', '男', '男', '女', '男', '女', '女'],
'age': [23, 22, 21, 100000, 20, 20 ,20]
})
# 表名
df.to_sql(mysql_table, con=engine, if_exists='append', index=False)
"""
to_sql參數:(比較重要)
if_exists:表如果存在怎麼處理
append:追加
replace:刪除原表,建立新表再添加
fail:什麼都不幹
chunksize: 默認的話是一次性導入, 給值的話是批量導入,一批次導入多少
index=False:不插入索引index
dtype 創建表結構
需要導入 import sqlalchemy
dtype = {'id': sqlalchemy.types.BigInteger(),
'name': sqlalchemy.types.String(length=20),
'sex': sqlalchemy.types.String(length=20),
'age': sqlalchemy.types.BigInteger(),
})
"""
if __name__ == '__main__':
main()
方法3
spark不能直接讀Excel等數據,可以先將數據寫入到json文件中
import pandas as pd
import json
def data_to_json():
"""
數據寫入json
:return:
"""
df = pd.DataFrame({
'name': ['戴沐白', '奧斯卡', '唐三', '小舞', '馬紅俊', '寧榮榮', '朱竹清'],
'sex': ['男', '男', '男', '女', '男', '女', '女'],
'age': [23, 22, 21, 100000, 20, 20, 20]
})
data_json = df.to_dict(orient='records')
for dt in data_json:
dt_string = json.dumps(dt, ensure_ascii=False)
with open('data.json', 'a+', encoding='utf-8') as f:
f.write('{}\n'.format(dt_string))
if __name__ == '__main__':
data_to_json()
from pyspark import SQLContext
from pyspark.sql import SparkSession
import pyspark.sql.functions as F
mysql_host = 'localhost'
mysql_db = 'test'
mysql_user = 'root'
mysql_pwd = '123456'
mysql_table = 'data_to_mysql'
def sparkConfig():
"""
spark的配置
:return:
"""
spark = SparkSession\
.builder\
.appName('data_to_mysql')\
.master('local[*]') \
.getOrCreate()
sql = SQLContext(spark)
return sql, spark
def readJson(spark):
data = spark.read.json('data.json')
data.show()
data.printSchema()
print(dir(F))
# 兩種方法都可以更改列名
# data.select(F.col('old_field1').alias('new_field1'), F.col('new_field2').alias('new_field2')).show()
# data = data.withColumnRenamed('old_field', 'new_field')
data.show()
url = 'jdbc:mysql://{}:3306/{}?useUnicode=true&characterEncoding=utf8'.format(mysql_host, mysql_db) # 有中文,需處理中文亂碼
table = mysql_table
auth_mysql = {"user": mysql_user, "password": mysql_pwd}
data.write.jdbc(url, table, mode='append', properties=auth_mysql)
"""
* `append`: 數據追加
* `overwrite`: 如果數據存在則覆蓋
* `error`: 如果數據已經存在,則拋出異常。
* `ignore`: 如果數據已經存在,則忽略此操作。
"""
def main():
sql, spark = sparkConfig()
readJson(spark)
if __name__ == '__main__':
main()