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

Mapping table with data files based on data type of the data file using python?

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

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

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

我的数据文件就像下面的文件名一样,也不是固定的 nemas 即它会改变

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

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

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

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

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

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

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

>>> 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 ..)我只转换 string,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']]

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