在(Py)Spark中读取JDBC源时出现不支持的数组错误?

时间:2018-05-30 22:06:08

标签: python apache-spark pyspark apache-spark-sql pyspark-sql

尝试将postgreSQL数据库转换为Dataframe。以下是我的代码:

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("Connect to DB") \
    .getOrCreate()

jdbcUrl = "jdbc:postgresql://XXXXXX" 
connectionProperties = {
  "user" : " ",
  "password" : " ",
  "driver" : "org.postgresql.Driver"
}

query = "(SELECT table_name FROM information_schema.tables) XXX"
df = spark.read.jdbc(url=jdbcUrl, table=query, properties=connectionProperties)

table_name_list = df.select("table_name").rdd.flatMap(lambda x: x).collect() 
    for table_name in table_name_list:
          df2 = spark.read.jdbc(url=jdbcUrl, table=table_name, properties=connectionProperties)

我收到错误:

  

java.sql.SQLException:为表名生成df2时不支持的类型ARRAY

如果我硬编码表名值,我不会得到相同的错误

df2 = spark.read.jdbc(jdbcUrl,"conditions",properties=connectionProperties) 

我检查了table_name类型,它是String,这是正确的方法吗?

1 个答案:

答案 0 :(得分:1)

我想您不希望属于postgres内部工作的表名,例如pg_typepg_policies等其架构类型为pg_catalog的导致错误的spark.read.jdbc(url=jdbcUrl, table='pg_type', properties=connectionProperties)

  

py4j.protocol.Py4JJavaError:调用o34.jdbc时发生错误。   :java.sql.SQLException:不支持的类型ARRAY

当您尝试将其视为

applicable_roles

并且有view_table_usageinformation_schema等表格,其架构的类型为spark.read.jdbc(url=jdbcUrl, table='view_table_usage', properties=connectionProperties) ,导致

  

py4j.protocol.Py4JJavaError:调用o34.jdbc时发生错误。   :org.postgresql.util.PSQLException:错误:关系" view_table_usage"不存在

当您尝试将其视为

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("Connect to DB") \
    .getOrCreate()

jdbcUrl = "jdbc:postgresql://hostname:post/" 
connectionProperties = {
  "user" : " ",
  "password" : " ",
  "driver" : "org.postgresql.Driver"
}

query = "information_schema.tables"
df = spark.read.jdbc(url=jdbcUrl, table=query, properties=connectionProperties)

table_name_list = df.filter((df["table_schema"] != 'pg_catalog') & (df["table_schema"] != 'information_schema')).select("table_name").rdd.flatMap(lambda x: x).collect() 
    for table_name in table_name_list:
          df2 = spark.read.jdbc(url=jdbcUrl, table=table_name, properties=connectionProperties)

可以使用上面的jdbc命令将模式类型为public的表读入表中。

  
    

我检查了table_name类型,它是String,这是正确的方法吗?

  

因此您需要过滤掉这些表名并将您的逻辑应用为

{{1}}

那应该有用