Great Expectations连接Redshift时查询未使用Schema名的问题
Great Expectations构建查询未使用Schema名的问题解决
问题现象
使用Great Expectations的Table Asset构建查询时,生成的SQL语句未包含指定的Schema名,导致报错relation "bar" does not exist,手动将查询中的bar改为foo.bar后可正常执行。
原代码实现
import great_expectations as gx from sqlalchemy_extras.sqlalchemy_utils import get_credentials, get_connection_string # 团队内部获取连接信息的方法,无需关注细节 # 生成的连接字符串格式:'redshift+psycopg2://USER:PASS@HOST:PORT/DB_NAME' def get_gx_datasource(gx_context, db_name): settings = get_credentials().get(db_name) redshift_connection_string = str(get_connection_string(settings)) return gx_context.sources.add_sql(connection_string=redshift_connection_string, name=db_name) gx_context = gx.get_context() expectation_suite = gx_context.add_expectation_suite(expectation_suite_name='my_suite') gx_datasource = get_gx_datasource(gx_context, db_name='db_name') gx_datasource.add_table_asset( name='bar', table_name='bar', schema_name='foo' ) asset = gx_datasource.get_asset('bar') asset.add_splitter_mod_integer(column_name='my_col', mod=10) batch_request = asset.build_batch_request() batches = gx_datasource.get_batch_list_from_batch_request(batch_request) for batch in batches: print(batch.batch_spec)
报错信息
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "bar" does not exist [SQL: SELECT distinct(mod(CAST(my_col AS INTEGER), %(mod_1)s)) AS distinct_1 FROM bar] [parameters: {'mod_1': 10}]
已尝试的无效方法
- 同时指定
table_name为foo.bar和schema_name为foo - 仅指定
table_name为foo.bar - 直接编辑table_asset对象的数据
解决方案
1. 升级Great Expectations版本
部分旧版本的SQL数据源组件在处理schema_name参数时存在逻辑bug,升级到v0.15.0及以上的稳定版本可修复该问题。
2. 数据源级别设置默认Schema
若当前业务场景下大部分表都属于同一Schema,可在添加SQL数据源时指定default_schema参数,后续所有Table Asset都会默认使用该Schema:
def get_gx_datasource(gx_context, db_name): settings = get_credentials().get(db_name) redshift_connection_string = str(get_connection_string(settings)) return gx_context.sources.add_sql( connection_string=redshift_connection_string, name=db_name, default_schema='foo' # 添加默认Schema配置 )
3. 直接指定带Schema的表名(避免参数冲突)
如果不需要全局默认Schema,可直接在table_name中传入带Schema的完整表名,不要同时指定schema_name参数,避免参数解析冲突:
gx_datasource.add_table_asset( name='bar', table_name='foo.bar' # 直接使用带Schema的表名 )
4. 手动修正Batch查询语句(临时方案)
若上述方法均无法生效,可在获取Batch后手动修改查询语句,强制加上Schema:
for batch in batches: # 替换查询中的表名为带Schema的版本 batch.batch_spec.query = batch.batch_spec.query.replace('FROM bar', 'FROM foo.bar') # 执行后续的Expectation验证操作
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

