目录
十六、一个python脚本:生成从mysql到hdfs的datax的全量json脚本
十七、一个python脚本:生成从mysql到hdfs的datax的增量json脚本
一、关于打开文件两种方式
"""第一种使用print进行输出,输出的目的地是文件"""
fp = open(r"D:\test.txt","w")
print("这是利用print输出",file = fp)
fp.close()
"""第二种 使用文件读写操作进行输出"""
with open(r"D:\aa.txt","w") as file:
file.write("这是利用with 进行输出的")
二、lambda函数和map函数
"""lambda"""
"""一 创建匿名函数"""
#正常写法
def sum_a_b1(a,b):
return a+b
print(sum_a_b1(10,20))
#lambda 写法
#默号前面是参数 默号后面是执行的逻辑
sum_a_b2 = lambda x,y : x+y
print(sum_a_b2(10,30))
"""二 和map函数共用"""
pingfang = lambda x:x**2
a=[1,2,3]
#map 会映射list中每一个值 做func 处理
#使用list处理成列表打印出
print(list(map(pingfang,a)))
三、数组 * 数字
a = [1,2]
print(a*2)
# 打印结果:
# [1,2,1,2]
# 在Python3中对于数组、字符串的 * 表示对原数组、字符串的复制,所以 a * 2 表示对列表a的复制,结果为 [1,2,1,2]
# 而且在Python3中字符串、列表和元组支持此种方法复制数据,字典和集合不行
四、除法在py2.0与py3.0区分
print(type(1/2))
# Python2 中除法默认向下取整,因此 1/2 = 0,为整型。
# Python3 中的除法为正常除法,会保留小数位,因此 1/2 = 0.5,为浮点型。
五、python的闭包操作
"""闭包操作
闭包;
函数内的属性,都是有生命周期的,都是在函数执行期间
内部函数 对外部函数 作用域里的变量 的引用
闭包内的闭包函数私有化了变量,完成了数据的封装,类似于面向对象
"""
# 例子1
def func(): #外部函数
a = 1 #外部函数作用域里的变量
print("func")
def func1(num): #内部函数
print("func1")
print(num+a)
return func1
var = func()
var(3)
#例子2
mylist = [1,2,3,4]
def a(mylist):
print("初始list:",mylist)
def b():
mylist[0]+=1
print("操作list:",mylist)
return b
c = a(mylist)
c()
c()
六、Python 的 replace函数用法
"""字符串的replace 方法,如果有2个参数表示将字符串中的某个字符替换成另外一个字符,如果有3个字符,
最后一个参数指的是:替换最大数,实例如下:
a = "hello"
print(a.replace('l','*',2)) 因为最后一个参数是2,所以,最大替换数为:2,所以结果为:he**o
"""
a = "helllo"
print(a.replace('l','*',2))
七、global声明
"""
当内部作用域想修改外部变量时,需要使用global声明。
"""
counter = 1
def doLotsOfStuff():
global counter
for i in (1, 2, 3):
counter += 1
doLotsOfStuff()
print(counter)
八、编码解码
"""
有一段python的编码程序如下,请问经过该编码的字符串的解码顺序是
urllib.quote(line.decode("gbk").encode("utf-16"))
题目中的代码是一个编码过程:
编码:decode()
解码:encode()
url编码:urllib.quote()
line.decode("gbk") 可知 line 是 gbk 编码的
编码过程:
line -> 解码 gbk -> 编码 utf-16 -> 编码 url
解码过程(与编码过程相反):
解码 url -> utf-16 -> gbk
"""
九、字符串的 find 与 index 区别
"""
find:找到返回第一个位置索引,找不到返回-1 str.find(str1,a) a为索引开始处,默认0
index:找到返回第一个位置索引,找不到报ValueError
"""
strs = 'I like python'
one = strs.find('a')
print(one)
two = strs.index('a')
print(two)
十、Python中 sys.argv[]的用法
1、解释
sys.argv[] 是从一个程序从外部获取参数的桥梁,并且我们获取的参数可以是多个,所以获取的是一个list列表,也就是我们可以将sys.argv[] 看做一个列表,所以我们可以用 [] 提取其中的元素,其中在这些元素中,第一个元素是我们的程序本身,随后,是依次从外部获取的参数。
2、例子解释
(1)首先 sys.argv[0] 代表我们文件的本身
#代码如下
import sys
print(sys.argv[0])
#输出如下
# D:/pythontest/plane/实操/test2.py
(2) argv[0]
cmd 进入到我们的 文件存储目录
执行我们的文件如下
(3) argv[1]
再次执行 并在后面加一个参数,如下
(4) argv[2:]
import sys
print(sys.argv[2:])
执行如下
代表 从输入的第二个参数,包括第二个参数
(5) argv[2:4]
import sys
print(sys.argv[2:4])
执行如下
代表 从输入的第二个参数,到第四个参数,包括第二个参数,不包括第四个参数
(6)argv
import sys
print(sys.argv)
执行如下
十一、python中 getopt() 函数的使用
1、解释
在使用python脚本时,有时会需要传入不同的参数来实现不同的功能。
目前有 短选项 和 长选项 两种格式
段选择格式为: - 加上一个字母 ,比如: -p
长选项格式为:-- 加上一个单词,比如; --name
2、用法
(1)简单诠释
代码如下
import sys
import getopt
option,args = getopt.getopt(sys.argv[1:],'ht:',['help','filename='])
print(option)
print(args)
解释:
短选项若不接受参数 直接 参数即可如上 h 即可 ,若要接收参数,则参数后加一个 :即可,如上 t:
长选项需要用方括号包住,如上,若不接受参数值,直接变量名即可 如上 help,若要接受参数值参数后加一个 = 即可,如上。
并且 getopt.getopt(sys.argv[1:],'ht:',['help','filename=']) 返回的是一个两元组的列表
执行结果如下
(2)代码使用
由(1)我们得知getopt的基本用法,下面用一个简单代码诠释
代码如下
import sys
import getopt
option , args= getopt.getopt(sys.argv[1:],'-h-t:',['help','filename='])
for opt_name,opt_value in option:
if opt_name in('-h','--help'):
print("----help----")
if opt_name in('-t'):
print("--t-- is",opt_value)
if opt_name in('--filename'):
print('--filename--',opt_value)
执行结果如下:
十二、python的JSON使用
import json
# 构建一个json格式的字典
person = {"name":"zhangsan","address":"shanghai","tel":["123456","654321"],"is_only":True}
print(type(person))
print(person)
## dumps 是将格式转换为 str
## dump 必须要和文件在一起操作 有文件指针
## 同理 load 和 loads与其用法相反
# 将构建的json格式的python对象转换为 str
# indent = 4 可以将格式化 str,更加便于阅读
new_person = json.dumps(person,indent=4)
print(type(new_person))
print(new_person)
# 将dict 格式化并存储在文件中
with open('test1.json','w') as f:
json.dump(person,f,indent=4)
十三、格式化赋值与输出
def test(a,b):
txt = 'aaaa is %s , bbbb is %s'
print(txt %(a,b))
print('cccc is %s ,dddd is %s'%(a,b))
if __name__ == '__main__':
a = input("a:")
b = input("b:")
test(a,b)
十四、cursor.execute 对sql语句赋值的格式
## 传参模式如下
cursor.execute(sql,[database,table])
##其中 database table为变量 ,格式如此
十五、join()函数和os.path.join()
"""
join 语法
'sep'.join(seq)
sep为 连接符,可以为空
seq要连接的元素的序列、字符串、元组、字典
"""
path = '.'.join(['a','b','c'])
print(path)
"""打印结果为
a.b.c
"""
十六、一个python脚本:生成从mysql到hdfs的datax的全量json脚本
1、脚本编写如下
#coding=utf-8
import getopt
import json
import os
import sys
import MySQLdb
# mysql 连接信息
mysql_host = 'hadoop'
mysql_port = '3306'
mysql_user = 'root'
mysql_passwd = '123456'
#HDFS 连接信息
hdfs_node = "hadoop"
hdfs_port = "9000"
# 生成文件所在的的路径
out_path = "/home/peizk/pytest"
# 生成 mysql连接信息
def mysql_connect():
return MySQLdb.connect(host=mysql_host,port=int(mysql_port),user=mysql_user,passwd=mysql_passwd)
# 获取相关数据库里表的信息
def mysql_meta(database,table):
connect = mysql_connect()
cursor = connect.cursor()
sql = ("""SELECT
COLUMN_NAME
,DATA_TYPE
from
information_schema.COLUMNS
WHERE
TABLE_SCHEMA= %s AND TABLE_NAME= %s
ORDER BY
ORDINAL_POSITION """)
## 传参模式如下
cursor.execute(sql,[database,table])
### fetchall 获取的是一个元组
fetchall = cursor.fetchall()
cursor.close()
connect.close()
return fetchall
# fetchall 获取的是一个元组 , 通过 lambda 函数获取我们所需的值
def mysql_col(database,table):
meta = mysql_meta(database,table)
# print(list(map(lambda x: x[0],meta)))
# print(list(map(lambda x: x[1], meta)))
return map(lambda x: x[0],meta)
# 获取mysql字段对应的hive的字段和类型
def hive_col(database,table):
# hive类型转换
def type_map(mysql_type):
mapping = {
"bigint": "bigint",
"int": "bigint",
"smallint": "bigint",
"tinyint": "bigint",
"decimal": "string",
"double": "double",
"float": "float",
"binary": "string",
"char": "string",
"varchar": "string",
"datetime": "string",
"time": "string",
"timestamp": "string",
"date": "string",
"text": "string"
}
return mapping[mysql_type]
fetchall = mysql_meta(database,table)
return map(lambda x: {"name": x[0],"type": type_map(x[1])},fetchall)
def generate_json(database,table):
job = {
"job": {
"content": [{
"reader": {
"name": "mysqlreader",
"parameter": {
"column": list(mysql_col(database, table)),
"connection": [{
"jdbcUrl": ["jdbc:mysql://" + mysql_host + ":" + mysql_port + "/" + database],
"table": [table]
}],
"password": mysql_passwd,
"username": mysql_user,
"where": "1=1"
}
},
"writer": {
"name": "hdfswriter",
"parameter": {
"column": list(hive_col(database,table)),
"compress": "snappy",
"defaultFS": "hdfs://" + hdfs_node + ":" + hdfs_port,
"fieldDelimiter": "\t",
"fileName": table,
"fileType": "orc",
"path": "${hdfs_path}",
"writeMode": "append"
}
}
}],
"setting": {
"speed": {
"channel": "1"
}
}
}
}
if not os.path.exists(out_path):
os.makedirs(out_path)
with open(os.path.join(out_path,'.'.join([database,table+'full','json'])),'w') as f:
json.dump(job,f,indent=4)
# 接收脚本外部传的参数,执行脚本
def main(args):
database = ''
table = ''
option,opt_aa = getopt.getopt(sys.argv[1:],'d:t:',['database=','table='])
for opt,opt_value in option:
if opt in ('-d','--database'):
database = opt_value
if opt in ('-t','--table'):
table = opt_value
# 调用脚本
generate_json(database,table)
# main函数
if __name__ == '__main__':
main(sys.argv)
2、测试如下
使用 datax执行
[peizk@hadoop pytest]$ datax.py project.activity_infofull.json -p "-Dhdfs_path=/user/hive/warehouse/project.db/ods_activity_info_full/pt=2022-01-01"
十七、一个python脚本:生成从mysql到hdfs的datax的增量json脚本
1、脚本如下:
# coding=UTF-8
"""
增量脚本
在全量的基础上进行改进
对sql语句进行优化
取增量数据 需要根据 create_time 和 update_time 两个一起进行判断
"""
import getopt
import json
import os.path
import sys
import MySQLdb
# mysql 连接信息
mysql_host = 'hadoop'
mysql_port = '3306'
mysql_user = 'root'
mysql_passwd = '123456'
# hadoop 连接信息
hadoop_host = 'hadoop'
hadoop_port = '9000'
# 生成脚本存储linux位置
out_path = '/home/peizk/pytest/test'
# mysql 连接
def mysql_connect(database,table):
return MySQLdb.connect(host=mysql_host,port=int(mysql_port),user=mysql_user,passwd=mysql_passwd)
# 取得表中对应数据和类型的全部游标显示
def mysql_cursor(database,table):
connect = mysql_connect(database,table)
cursor = connect.cursor()
sql = "SELECT COLUMN_NAME,DATA_TYPE from information_schema.COLUMNS WHERE TABLE_SCHEMA=%s AND TABLE_NAME=%s ORDER BY ORDINAL_POSITION"
cursor.execute(sql,[database,table])
meta = cursor.fetchall()
cursor.close()
connect.close()
return meta
# 获取Datax所需的mysql字段
def mysql_col(database,table):
return map(lambda x : x[0],mysql_cursor(database,table))
# 获取Datax所需的对应hive字段
def hive_col(database,table):
def map_col(str):
mapping = {
"bigint": "bigint",
"int": "bigint",
"smallint": "bigint",
"tinyint": "bigint",
"decimal": "string",
"double": "double",
"float": "float",
"binary": "string",
"char": "string",
"varchar": "string",
"datetime": "string",
"time": "string",
"timestamp": "string",
"date": "string",
"text": "string"
}
return mapping[str]
return map(lambda x :{"name" : x[0],"type" : map_col(x[1])},mysql_cursor(database,table))
# 增量表同步 sql 语句获取,注意start_date和end_date要用‘’包裹
def sql_query(database,table):
sql_col = ','.join(list(mysql_col(database,table)))
sql = "select "+sql_col+" from "+table+" where (${create_time}>=\'${start_date}\' and ${create_time}<\'${end_date}\') ${or} (${update_time}>=\'${start_date}\' and ${update_time}<\'${end_date}\')"
return sql
# 生成增量表JSON
def generate_json(database,table):
job = {
"job": {
"content": [
{
"reader": {
"name": "mysqlreader",
"parameter": {
"connection": [
{
"jdbcUrl": ["jdbc:mysql://"+mysql_host+":"+mysql_port+"/"+database],
"querySql": [sql_query(database,table)]
}
],
"password": mysql_passwd,
"username": mysql_user,
"splitPk": ""
}
},
"writer": {
"name": "hdfswriter",
"parameter": {
"column": list(hive_col(database,table)),
"compress": "snappy",
"defaultFS": "hdfs://"+hadoop_host+":"+hadoop_port,
"fieldDelimiter": "\t",
"fileName": table,
"fileType": "orc",
"path": "${hdfs_path}",
"writeMode": "append"
}
}
}
],
"setting": {
"speed": {
"channel": "1"
}
}
}
}
return job
# 运行主程序,接受参数
def main(args):
database = ''
table = ''
opt1,opt2 = getopt.getopt(args[1:],'d:t:',['database=','table='])
for opt_name,opt_value in opt1:
if opt_name in ('-d','--database'):
database = opt_value
if opt_name in ('-t','--table'):
table = opt_value
job = generate_json(database,table)
#将生成 josn 存储在linux上
if not os.path.exists(out_path):
os.makedirs(out_path)
with open(out_path+"/"+table+".json",'w') as f:
json.dump(job,f,indent=4)
# main函数
if __name__ == '__main__':
main(sys.argv)
2、生成json脚本
[peizk@hadoop test]$ python a.py -d project -t seller_info
3、执行json脚本
[peizk@hadoop test]$ datax.py seller_info.json -p "-Dhdfs_path=/user/hive/warehouse/project.db/ods_seller_info_incr/pt=2022-01-01 -Dcreate_time=create_time -Dstart_date='2022-01-01' -Dend_date='2022-01-02' -Dupdate_time=update_time -Dor=or"