Spark SQL基于JDBC数据源创建持久化全局视图失败问题
Spark SQL创建JDBC持久化全局视图触发ParseException错误
配置信息
tbl_in = myjdbctable tbl_out = myview db_user = 'myuser' db_pw = 'mypw' jdbc_url = 'jdbc:sqlserver://myserver.domain:1433;database=mydb'
可行代码(会话级临时视图)
创建会话级临时视图的代码可正常执行:
query = f""" create or replace temporary view {tbl_out} using jdbc options( dbtable '{tbl_in}', user '{db_user}', password '{db_pw}', url '{jdbc_url}' ) """ spark.sql(query) # 输出:DataFrame[]
报错代码(持久化全局视图)
尝试创建常规持久化全局视图时触发错误:
query = f""" create or replace view {tbl_out} using jdbc options( dbtable '{tbl_in}', user '{db_user}', password '{db_pw}', url '{jdbc_url}' ) """ spark.sql(query) # 触发ParseException
错误信息
ParseException: mismatched input 'using' expecting {'(', 'UP_TO_DATE', 'AS', 'COMMENT', 'PARTITIONED', 'TBLPROPERTIES'}(line 3, pos 0) == SQL == create or replace view myview using jdbc ^^^ options( dbtable 'myjdbctable', user 'myuser', password '[REDACTED]', url 'jdbc:sqlserver://myserver.domain:1433;database=mydb' )
问题原因
Spark SQL对临时视图和持久化视图的语法规则存在差异:
- 临时视图仅在当前会话有效,无需持久化到元数据,支持直接用
using绑定数据源,语法更灵活。 - 持久化视图属于全局元数据对象,必须基于明确的
AS SELECT查询语句定义,不能直接使用using语法绑定数据源。
解决办法
方案1:通过DataFrame创建持久化视图
先读取JDBC数据源生成DataFrame,再将DataFrame注册为持久化视图:
# 读取JDBC数据 df = spark.read.format("jdbc").options( dbtable=tbl_in, user=db_user, password=db_pw, url=jdbc_url ).load() # 创建或替换持久化视图 df.createOrReplaceView(tbl_out)
方案2:在CREATE VIEW中使用AS SELECT查询JDBC数据源
修改SQL语句,用AS SELECT * FROM jdbc OPTIONS(...)的形式定义视图:
query = f""" CREATE OR REPLACE VIEW {tbl_out} AS SELECT * FROM jdbc OPTIONS( dbtable '{tbl_in}', user '{db_user}', password '{db_pw}', url '{jdbc_url}' ) """ spark.sql(query)
内容的提问来源于stack exchange,提问作者Triamus
相关产品推荐
相关产品推荐

