AnalysisException:不允许添加数据库前缀

时间:2018-08-16 06:54:03

标签: apache-spark apache-spark-sql

我正在尝试使用JDBC从处于模式的表中读取数据。但是,出现错误:

org.apache.spark.sql.AnalysisException: It is not allowed to add database prefix `myschema` for the TEMPORARY view name.;

代码非常简单明了,第三行出现错误(包括其他内容只是为了说明我在做什么)。 myOptions包括url,dbtable,驱动程序,用户,密码。

SQLContext sqlCtx = new SQLContext(ctx);
Dataset<Row> df = sqlCtx.read().format("jdbc").options(myOptions).load();

df.createOrReplaceTempView("myschema.test_table");
df = sqlCtx.sql("select field1, field2, field3 from myschema.test_table");

因此,如果不允许使用数据库/模式限定符,那么如何为表引用正确的限定符?忽略它会在数据库中提供一个“无效的对象名称”。

我在数据库端唯一的选择是使用默认模式,但是这是基于用户而不是基于会话的,因此我必须为要访问的每个模式创建一个用户和连接。

我在这里想念什么?这似乎是一个常见的用例。

编辑:对于那些试图关闭此文件的人……“一个无法再现的问题或简单的印刷错误”关于关闭原因的评论又如何呢?如果我有错字或简单的错误,请发表评论并告诉我。我不能成为遇到这个问题的唯一人。

Spark 1.2中的

registerTempTable曾经以这种方式工作,我们被告知createOrReplaceTempView应该在2.x中替换它。但是功能还不存在。

2 个答案:

答案 0 :(得分:1)

我知道了。

简短的答案是... dbtable名称和temp视图/表名称是两个不同的东西,不必具有相同的值。 dbtable定义用于在数据库中获取数据,临时视图/表用于定义在Spark SQL中的调用方式。

这一开始很令人困惑,因为在Spark 1.6中,它允许视图名称与全表名称匹配(因此,我正在使用的软件将其插入1.6中。)如果您是手工编写的,则只需为临时表或视图1.6或2.2使用非限定的表名。

为了在Spark 1.6中的架构中引用表,我必须执行以下操作,因为dbtable和视图名称相同:

1. dbtable to "schema.table"
2. registerTempTable("schema.table")
3. Reference table as `schema.table` (include the ticks to treat the entire thing as an identifier to match the view name) in the SQL

但是,在Spark 2.2中,您需要这样做,因为视图名称中不允许使用架构/数据库:

1. dbtable to "schema.table"
2. createOrReplaceTempView("table")
3. Reference table (not schema.table) in the SQL (matching the view)

答案 1 :(得分:0)

我猜您正在尝试从RDBMS提取特定表。如果您使用的是Spark 2.x或更高版本,则可以使用以下代码在数据框中获取ur表。

DF = spark.read \
.format("jdbc") \
.option("url", "jdbc:oracle:thin:username/password@//hostname:portnumber/SID") \
.option("dbtable", "hr.emp") \
.option("user", "db_user_name") \
.option("password", "password") \
.option("driver", "oracle.jdbc.driver.OracleDriver") \
.load()