背景
公司研发了一个系统——基于客户交易行为,利用算法得出各个用户的各式各样的特征,暂且称之为“标签”。这些“标签”是利用大数据平台计算而得的结果。计算得到的近三四百个“标签“数据会会落到中台N张表中。操作员,在管理平台,能够通过特定”标签“获取某类满足此”标签“的用户,或者搜索某个用户的账户,查询该用户的”标签“。
在测试过程中,没有数据是一个很苦恼的事情。手工插入数据,三四百个字段,插入十条后,人也瘫了。于是想:可否用一个脚本实现。
分析
分析下功能:
1、上述两个场景中,不管是查满足某”标签“的用户还是查某用户的”标签“都是通过条件去数据库取数据即可,不需要对数据进行处理(在大数据层已经处理好了)。那么,数据间不存在业务逻辑。
2、如何确定插入数据的值?可这么处理:通过desc table 来获取该表的各个字段,以及字段类型,字段长度。根据这些信息,可造符合条件的数据。
实现
上面确认了可行性。接下来就是实现了。
创建一个Generate_Data类,写一个方法,获取表字段相关信息。如下:
class Generate_Data:
def get_cols(self,table):
"""获取表字段名、字段类型"""
sql = "desc " + table
cur.execute(sql)
result = cur.fetchall()
return result
在sql中结果是:
获取到数据后,解析上述type列的字段,得到字段类型,字段长度(像date就没有字段长度标识)。比如解析上述 fund_acccount 得到类型:varchar,长度:32。对于数值型的数据 有可能还有正负之分。比如tinyint 类型:若无正负,即unsined ,范围为:[0,255];若有正负之分,范围为:[-128,127]。
for col in columns:
col_name = col[0]
col_type_info = col[1]
index = int(col_type_info.rfind("(")) # 通过左右括号获取括号内的数据
# 处理无长度字段 eg:date
if index == -1:
col_type = col_type_info
else:
col_type = col_type_info[:index]
# 处理数值类型有符号与无符号
if "unsigned" in col_type_info:
is_unsigned = 1
else:
is_unsigned = 2
接下来是造符合各字段的数据(以下为常用的一些类型作了处理)
# 对于不同类型的字段,生成数据值的格式、内容等处理
# char,varchar
if "char" in col_type:
col_length = int(col_type_info[index + 1:-1]) # 获取字段允许长度
if len(col_name) > (col_length-6):
if col_length < 6:
value = str(random.randint(0, 9*10**col_length))
else:
value = str(random.randint(0, random_range))
else:
value = col_name + str(random.randint(0, random_range))
insert_sql = "{0}'{1}',".format(insert_sql, value)
elif col_type == "tinyint":
# 编码为gbk时,每个字符最多占2个字节;编码为utf8时,每个字符最多占3个字节;此处以utf8编码占用空间计算,下同
random_range = 255//(3*1*is_unsigned)
value = random.randint(g(is_unsigned,random_range), random_range)
insert_sql = (insert_sql + "%d,") % value
elif col_type == "smallint":
random_range = 65535//(3*2*is_unsigned) # 除考虑编码外,每个数字占用2个字节
value = random.randint(g(is_unsigned,random_range), random_range)
insert_sql = (insert_sql + "%d,") % value
elif col_type == "mediumint":
random_range = 65535//(3*2*is_unsigned) # 除考虑编码外,每个数字占用2个字节
value = random.randint(g(is_unsigned,random_range),