使用python根据数据文件的数据类型映射表与数据文件?

Posted

技术标签:

【中文标题】使用python根据数据文件的数据类型映射表与数据文件?【英文标题】:Mapping table with data files based on data type of the data file using python? 【发布时间】:2018-10-09 06:25:49 【问题描述】:

我有 4 个文本文件,2 个文件包含数据库表的详细信息,其他 2 个包含数据,如下所示。

table1.txt
ename:varchar(10)
eid:smallint(5)
esal:numeric(10,3)

table2.txt
sid:smallint(5)
sname:varchar(10)
sclass:varchar(10)

我的数据文件如下所示,文件名也不是固定的,即它会改变

file1.txt:
aa,1,12222.009
bb,2,12345.012

file2.txt
1,s1,1st_class
2,s2,2nd_class

所以现在我想根据数据的数据类型映射哪个文件匹配将匹配哪个表。我的预期输出应该如下所示。

我的预期输出将在其他日志文件或打印语句中:

table1 matched data file is file2.txt.
table2 matched  data file is file1.txt.

【问题讨论】:

到目前为止你有什么尝试? 我曾尝试通过创建数据框来使用 pyspark,但它没有发生 我实际上.. 我需要两种方式。但python是主要的 如果是 Scala 答案..我可以转换成 python...我正在尝试我知道的两种方式(scala 和 python) 【参考方案1】:

实际上情况并不清楚,因此可能会有所不同。不过我可以给出一些建议。这不是确切的解决方案,但我认为它可以帮助您给出一个想法。

首先我阅读了表格的详细信息;

>>> rdd1 = sc.textFile('/home/ali/table1.txt')
>>> table1 = rdd1.map(lambda x: x.split(':')).map(lambda x: (x[0],x[1])).toDF(['col_name','data_type'])
>>> table1.show()
+--------+-------------+
|col_name|    data_type|
+--------+-------------+
|   ename|  varchar(10)|
|     eid|  smallint(5)|
|    esal|numeric(10,3)|
+--------+-------------+

>>> rdd2 = sc.textFile('/home/ali/table2.txt')
>>> table2 = rdd2.map(lambda x: x.split(':')).map(lambda x: (x[0],x[1])).toDF(['col_name','data_type'])
>>> table2.show()
+--------+-----------+
|col_name|  data_type|
+--------+-----------+
|     sid|smallint(5)|
|   sname|varchar(10)|
|  sclass|varchar(10)|
+--------+-----------+

我读取数据文件,但在此之前您应该定义模式。如果不这样做,所有列的数据类型将默认分配为字符串

>>> from pyspark.sql.types import StructType, StructField, DoubleType, IntegerType, StringType
>>> 
>>> schema1 = StructType([
...     StructField("col1", StringType()),
...     StructField("col2", IntegerType()),
...     StructField("col3", DoubleType())
... ])
>>> 
>>> schema2 = StructType([
...     StructField("col1", IntegerType()),
...     StructField("col2", StringType()),
...     StructField("col3", StringType())
... ])
>>> 
>>> data1 = spark.read.csv('/home/ali/file1.txt', schema=schema1)
>>> data1.show()
+----+----+---------+
|col1|col2|     col3|
+----+----+---------+
|  aa|   1|12222.009|
|  bb|   2|12345.012|
+----+----+---------+

>>> data2 = spark.read.csv('/home/ali/file2.txt', schema=schema2)
>>> data2.show()
+----+----+---------+
|col1|col2|     col3|
+----+----+---------+
|   1|  s1|1st_class|
|   2|  s2|2nd_class|
+----+----+---------+

我定义了一个函数来检查数据类型是否匹配。但是当你定义一个函数时,你应该转换一些数据库数据类型(例如:varchar -> string、numeric -> double ..)我只转换字符串、int 和 double 数据类型。如果您将使用更多数据类型,则应定义所有数据类型

>>> def matchTableData(t,d):
...     matched = []
...     for k1,table in t.items():
...             table_dtypes = []
...             a = True
...             for i in [i.data_type for i in table.select('data_type').collect()]:
...                     if 'char' in i:
...                             table_dtypes.append('string')
...                     elif 'int' in i:
...                             table_dtypes.append('int')
...                     elif 'numeric' in i:
...                             table_dtypes.append('double')
...             for k2,data in d.items():
...                     data_dtypes = [i[1] for i in data.dtypes]
...                     if table_dtypes == data_dtypes:
...                             matched.append([k1,k2])
...     return matched

现在我们准备比较数据类型。我为表和数据创建了两个字典。

>>> tables = 'table1':table1, 'table2':table2
>>> data = 'data1':data1, 'data2':data2
>>> print(matchTableData(tables,data))
[['table1', 'data1'], ['table2', 'data2']]

如您所见,它返回匹配的。正如我之前所说,它可能不是确切的解决方案,但我认为您可以使用其中的一部分

【讨论】:

嗨,感谢您的快速回复,但我无法创建 schema1 硬编码值 schema1 应该动态生成。在上面的答案(schema1,schema2)应该是动态的 您可以为此使用 Pandas。将熊猫导入为 pd data1 = spark.createDataFrame(pd.read_csv('/home/cloudera/ali/file1.txt')) 我可以使用 options(header='false', inferschema='true') 代替 pandas 吗?

以上是关于使用python根据数据文件的数据类型映射表与数据文件?的主要内容,如果未能解决你的问题,请参考以下文章

哈希表与布隆过滤器

Python学习之旅—DjangoORM基础

Data mapping-数据映射

IDEA插件系列(37):Easy Code插件——数据库表与java类代码快速生成

学习总结-hibernate设计表

学习总结-hibernate设计表