sql 忽略大小写_Flink使用Calcite解析Sql做维表关联(一)

本文探讨了在实时计算场景下,如何在Flink中使用SQL进行维表关联。传统方法通常涉及硬编码,而Flink 1.9引入了LookupableTableSource接口,支持同步或异步关联,提升了开发效率。在1.9之前,需要自定义SQL解析并转换为API。示例展示了包含维表关联的SQL语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9e0c93a3dfbb76e789ce9a23894e7e53.gif

点击箭头处“蓝色字”,关注我们哦!!

维表关联是离线计算或者实时计算里面常见的一种处理逻辑,常常用于字段补齐、规则过滤等,一般情况下维表数据放在MySql等数据库里面,对于离线计算直接通过ETL方式加载到Hive表中,然后通过sql方式关联查询即可,但是对于实时计算中Flink、SparkStreaming的表都是抽象的、虚拟的表,那么就没法使用加载方式完成。透过维表服务系列里面讲到的维表关联都是使用编码方式完成,使用Map或者AsyncIO方式完成,但是这种硬编码方式开发效率很低,特别是在实时数仓里面,我们希望能够使用跟离线一样sql方式完成维表关联操作。

在Flink1.9中提供了使用sql化方式完成维表关联,只需要实现LookupableTableSource接口即可,可以实现同步或者异步关联。在1.9之前就需要自己实现sql语法解析,然后在转换为API方式,对上层提供sql语法。看一个sql语句:

select * from orders o join gdsInfo g on o.gdsId=g.gdsId
orders表示流表,gdsInfo 表示维表。根据sql解析顺序先 from 部分、然后where 部分、最后select,那么对于join 方式,相当于join生成了一张临时表,然后去select 这张临时表,因此可以确认sql解析流程:1. 识别出流表与维表
2. 解析join部分,生成临时表3. select 临时表现在使用calcite解析这条语句
public class ParseDemo {
    
        public static void main(String[] args) {
    
            //假设gdsInfo就是维表        String sql = "select * from orders o join gdsInfo g on o.gdsId=g.gdsId";        SqlParser.Config config = SqlParser.configBuilder().setLex(Lex.MYSQL).build();        SqlParser sqlParser = SqlParser.create(sql, config);        SqlSelect sqlSelect = null;        try {
    
    
<think>我们正在解决用户遇到的错误:"Object information_schema not found"。这个错误Flink SQL引擎无法识别`information_schema`数据库。根据Flink的文档,`information_schema`是Flink提供的系统目录,用于查询元数据。但是,这个功能在Flink的某些版本中可能受到限制,或者需要特定的配置。 引用[1]中给出了Flink SQL的测试用例,创建了并查询,这说明了用户使用的是Flink SQL环境。而引用[2]是Flink 1.3版本的文档,说明用户可能使用的是较老的版本(但也不排除是旧文档的引用)。引用[3]提到了Hive配置的问题,但这里用户并没有使用Hive,所以暂时不考虑。引用[4]是关于DML语句的类型,与当前问题无关。 因此,我们重点考虑Flink SQL中`information_schema`的可用性。 根据Flink官方文档(最新版本),`information_schema`是在Flink 1.9版本开始引入的(具体引入版本需要确认,但1.3版本肯定没有)。因此,如果用户使用的是较老的Flink版本(低于1.9),则不会支持`information_schema`。 另外,即使版本支持,也可能因为以下原因导致错误: 1. 没有正确使用全大写:在Flink SQL中,系统数据库和名是大小写敏感的,通常需要大写。 2. 没有启用`information_schema`:在旧版本中可能需要配置。 3. 当前Catalog不支持:`information_schema`是每个Catalog下的,如果当前Catalog不是内置的默认Catalog(如内存Catalog)或者是自定义Catalog(如Hive Catalog)且不支持,则可能无法访问。 解决方案如下: 步骤1:确认Flink版本 执行以下SQL语句查看版本: ```sql SELECT CURRENT_VERSION(); ``` 如果版本低于1.9,则无法使用`information_schema`,需要升级或使用其他方式获取元数据。 步骤2:检查当前Catalog和Database 在Flink SQL中,默认的Catalog是`default_catalog`,默认的Database是`default_database`。`information_schema`位于每个Catalog下。因此,需要确保当前Catalog下存在`information_schema`。 可以尝试显式指定Catalog和Database: ```sql USE CATALOG default_catalog; USE DATABASE information_schema; SELECT * FROM `TABLES`; -- 注意:TABLES是保留字,需要用反引号 ``` 或者使用全限定名: ```sql SELECT * FROM default_catalog.information_schema.`TABLES`; ``` 步骤3:如果当前Catalog是自定义Catalog(如Hive Catalog),需要确认该Catalog是否支持`information_schema`。Flink的Hive Catalog在1.10版本之后才支持`information_schema`。 步骤4:如果以上步骤都不行,可以尝试使用其他方式获取信息,例如: - 使用`SHOW TABLES`命令: ```sql SHOW TABLES; ``` - 使用`DESCRIBE`命令: ```sql DESCRIBE [catalog_name.][db_name.]table_name; ``` 但是,这些命令不能完全替代`information_schema`的查询,因为它们只能列出名,不能提供丰富的元数据。 步骤5:如果用户使用的是Flink版本低于1.9且无法升级,可以考虑通过Flink的Table API获取元数据,或者通过查询底层存储系统的元数据(例如,如果是Hive,则通过Hive的元数据查询)。 示例:使用Table API获取信息(在Java/Scala程序中): ```java TableEnvironment tableEnv = ...; // 获取TableEnvironment // 获取Catalog Catalog catalog = tableEnv.getCatalog("default_catalog").orElse(null); // 获取数据库中的 for (String dbName : catalog.listDatabases()) { for (String tableName : catalog.listTables(dbName)) { CatalogBaseTable table = catalog.getTable(new ObjectPath(dbName, tableName)); // 打印信息 System.out.println(table.getUnresolvedSchema()); } } ``` 考虑到用户使用的是SQL客户端,可能无法直接使用Table API,因此还是以SQL操作为主。 总结:首先检查版本,然后检查当前Catalog,最后尝试使用全限定名。 下面给出个完整的查询示例(假设当前Flink版本>=1.9): ```sql -- 使用默认Catalog和information_schema数据库 SELECT * FROM default_catalog.information_schema.`TABLES` WHERE table_name = 'tb_agrt_policy_curr_dim_materialized'; ``` 注意:`TABLES`是保留字,必须用反引号括起来。 如果用户遇到的是大小写问题,也可以尝试小写(但根据文档,通常是大写): ```sql SELECT * FROM default_catalog.information_schema.tables -- 注意:有些版本可能名是小写 ``` 但是,根据Flink官方文档,`information_schema`中的名都是大写的,所以使用小写可能会出错。 如果用户仍然遇到`Object information_schema not found`,那么可能是当前Catalog不支持,可以切换回内置的默认Catalog: ```sql USE CATALOG default_catalog; ``` 然后再查询。 如果用户使用的是Hive Catalog,并且版本在1.10以上,可以尝试: ```sql USE CATALOG my_hive_catalog; -- 假设Hive Catalog名为my_hive_catalog SELECT * FROM information_schema.`TABLES`; ``` 如果还是不行,可能需要检查Hive Metastore的配置和权限。 最后,如果所有方法都无效,建议升级Flink到最新稳定版本。 相关问题: 1. 如何查看Flink SQL的当前Catalog和Database? 2. Flink SQL中如何切换Catalog? 3. 如何配置Flink使用Hive Catalog? 4. Flink SQL支持哪些系统? 5. 如何通过Flink SQL获取的列信息? 注意:在回答中,我们引用了用户提供的引用[1]和[2],但实际解决方案中,我们主要依据Flink的官方文档和常见问题解决经验。</think>### 解决 Flink SQL 查询 `information_schema` 报错 "Object information_schema not found" #### 🔍 问题原因分析 1. **Flink 版本限制** `information_schema` 是 Flink 1.11+ 新增的元数据功能[^2],旧版本(如 1.10 及更早)不支持该功能。 2. **Catalog 配置问题** `information_schema` 仅在默认内存 Catalog (`default_catalog`) 中可用: ```sql SHOW CURRENT CATALOG; -- 确认当前 Catalog /* 预期输出: +-----------------+ | current catalog | +-----------------+ | default_catalog | +-----------------+ */ ``` 3. **元数据存储未启用** 需要配置元数据存储才能使用系统功能: ```sql SET 'sql.catalog.metadata-store' = 'filesystem'; -- 启用元数据存储 ``` 4. **SQL 客户端配置缺失** 未在 `sql-client-defaults.yaml` 中启用元数据功能: ```yaml # sql-client-defaults.yaml execution: planner: blink type: streaming catalog: default_catalog metadata-store: filesystem # 关键配置 ``` #### ✅ 解决方案(逐步操作) ##### 步骤 1:确认 Flink 版本 ```sql SELECT CURRENT_VERSION(); /* 输出示例: +----------------+ | EXPR$0 | +----------------+ | 1.16.1 | -- 需 >=1.11 +----------------+ */ ``` ➜ **低于 1.11 版本**:需升级或使用替代方案(见文末) ##### 步骤 2:切换默认 Catalog ```sql USE CATALOG default_catalog; -- 切换到内置 Catalog USE DATABASE default_database; ``` ##### 步骤 3:启用元数据存储 ```sql -- 在 SQL 客户端中执行 SET 'sql.catalog.metadata-store' = 'filesystem'; SET 'sql.catalog.default.type' = 'generic_in_memory'; -- 内存存储 ``` ##### 步骤 4:正确查询系统 ```sql -- ✅ 正确写法 (注意保留字转义) SELECT * FROM information_schema.`TABLES` -- 使用反引号转义保留字 WHERE table_name = 'tb_agrt_policy_curr_dim_materialized'; ``` ##### 步骤 5:配置 SQL 客户端(持久化) 在 `conf/sql-client-defaults.yaml` 添加: ```yaml catalogs: - name: default_catalog type: generic_in_memory default-database: default_database metadata-store: filesystem ``` #### ⚠️ 旧版本替代方案(Flink <1.11) ```sql -- 方案1:使用SHOW命令 SHOW TABLES; -- 列出所有 DESCRIBE `tb_agrt_policy_curr_dim_materialized`; -- 查看结构 -- 方案2:通过Table API获取 TableEnvironment tEnv = ...; tEnv.listTables(); // 返回名数组 tEnv.getTable("tb_agrt_policy_curr_dim_materialized").getSchema(); ``` #### 💡 验证流程 ```mermaid graph TD A[启动Flink SQL客户端] --> B{版本≥1.11?} B -->|是| C[设置 metadata-store] B -->|否| D[使用SHOW/DESCRIBE] C --> E[USE CATALOG default_catalog] E --> F[SELECT FROM information_schema] F --> G[成功获取元数据] ``` #### 📚 相关配置参数 | 参数名 | 推荐值 | 作用 | |--------|--------|------| | `sql.catalog.metadata-store` | `filesystem` | 启用元数据存储 | | `sql.catalog.default.type` | `generic_in_memory` | 内置内存Catalog | | `sql-client.execution.planner` | `blink` | 使用Blink优化器 | | `sql-client.execution.type` | `streaming` | 流处理模式 | #### 📌 注意事项 1. **Hive Catalog 限制** `information_schema` 在 Hive Catalog 中不可用,需切换回 `default_catalog` 2. **权限要求** 需配置正确文件系统权限: ```yaml # flink-conf.yaml fs.allowed-fallback-filesystem: hdfs:// # 或 file:// ``` 3. **元数据持久化** 生产环境建议使用外部存储: ```sql SET 'sql.catalog.metadata-store' = 'database'; SET 'sql.catalog.metadata-store.db.url' = 'jdbc:mysql://...'; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值