通过ODBC连接Databricks查询S3 Delta表时提示‘表或视图未找到’错误
问题描述
通过ODBC从本地Python脚本连接Databricks集群,按照官方指南操作后能成功查询示例表samples.nyctaxi.trips,但查询S3存储桶中的Delta表时触发如下错误:
pyodbc.ProgrammingError: ('42S02', '[42S02] [Simba][SQLEngine] (31740) Table or view not found: .delta.s3://my-bucket/some/path/to/dataset/ (31740) (SQLExecDirectW)')
相同查询在同一集群的Databricks Notebook中可正常运行,使用的ODBC连接代码如下:
import pyodbc import os conn = pyodbc.connect( "Driver=/Library/simba/spark/lib/libsparkodbc_sb64-universal.dylib;" + f"Host={os.getenv('DATABRICKS_HOST')};" + "Port=443;" + f"HTTPPath={os.getenv('DATABRICKS_HTTP_PATH')};" + "SSL=1;" + "ThriftTransport=2;" + "AuthMech=3;" + "UID=token;" + f"PWD={os.getenv('DATABRICKS_TOKEN')}", autocommit = True ) # 执行SQL查询 cursor = conn.cursor() cursor.execute("SELECT * FROM samples.nyctaxi.trips") # 打印查询结果 for row in cursor.fetchall(): print(row)
解决方案
该问题源于Simba ODBC驱动对Spark SQL中Delta路径语法的解析逻辑和Notebook环境不一致,可通过以下几种方式解决:
方法1:创建临时视图中转查询
ODBC驱动不支持直接使用delta.前缀加路径的语法,可先创建临时视图再查询:
CREATE OR REPLACE TEMP VIEW temp_delta_view AS SELECT * FROM delta.`s3://my-bucket/some/path/to/dataset/`; SELECT * FROM temp_delta_view LIMIT 10;
将上述语句作为cursor.execute()的参数执行,即可绕过驱动的语法解析限制。
方法2:预注册外部表
在Databricks Notebook中将S3路径注册为外部表:
CREATE TABLE my_external_table USING delta LOCATION 's3://my-bucket/some/path/to/dataset/';
之后在ODBC连接中直接查询该注册表:
cursor.execute("SELECT * FROM my_external_table LIMIT 10")
这种方式稳定性更高,适合频繁访问的数据集。
方法3:添加ODBC连接属性
部分环境下,在连接字符串中添加SparkSQLDialect=1属性,可提升驱动对Spark SQL语法的兼容性:
conn = pyodbc.connect( "Driver=/Library/simba/spark/lib/libsparkodbc_sb64-universal.dylib;" + f"Host={os.getenv('DATABRICKS_HOST')};" + "Port=443;" + f"HTTPPath={os.getenv('DATABRICKS_HTTP_PATH')};" + "SSL=1;" + "ThriftTransport=2;" + "AuthMech=3;" + "UID=token;" + f"PWD={os.getenv('DATABRICKS_TOKEN')};" + "SparkSQLDialect=1", # 新增属性 autocommit = True )
添加后再尝试原查询语句,部分场景下可直接生效。
内容的提问来源于stack exchange,提问作者botchniaque
相关产品推荐
相关产品推荐

