语义视图的最佳实践¶
This section describes best practices for the development of data pipelines and data products that incorporate semantic views. These recommendations are primarily intended for data engineering and data science professionals who need assistance with the following development processes:
备注
本节不涉及 建模 语义视图的最佳实践。本节信息假设 Snowflake 语义视图采用迭代设计,并需要作为数据工程管道或数据产品的一部分进行管理。
所有权与数据访问权限¶
语义视图可以方便地访问存在于多个标准化数据源中的信息。语义层使思维从“如何查询特定数据源”转向“关注通过统一数据视图支持的用例和业务问题”。考虑到这一总体目标,数据工程团队和业务团队必须紧密协作。业务团队在业务案例方面具备专业知识,而数据工程团队则熟悉如何从表和视图中获取数据。两个团队都需要共同管理和拥有语义模型的所有权。
为了以兼顾双方需求的方式保护语义层,请使用基于角色的访问控制 (RBAC) 向语义视图及其依赖对象授予相应权限。如果从零开始,可以参考下一节中的 GRANT 语句序列,作为操作模板。但如果团队成员已经在开发、测试和生产环境中设置了权限,可能需要进行调整,或根据需要指引他们使用不同的角色。
授予对语义视图对象的权限¶
四类关键对象需要获得相应权限:
语义视图本身
语义视图定义中使用的表
语义视图定义中使用的视图
Cortex Search Service 对象(通常应用于视图和表中的分类数据)。
为了简化特定域的权限管理,Snowflake 建议在同一数据库架构下创建对象。然后,可以通过特定的自定义角色,向最终用户授予对该对象集合的访问权限。例如,对于“销售分析”Cortex Agent,您可以在 sales 数据库中创建一个 sales_analysis 架构,并专门创建一个角色,用于授予对语义视图及代理所需的其他数据(例如 snowflake_intelligence_sales_analysis_role)的访问权限。架构和角色就绪后,您应向该角色授予对未来对象的权限。
以下命令演示了这种方法:
-- Set variables for the specified role, database, and schema
SET my_role = 'snowflake_intelligence_sales_analysis_role';
SET my_db = 'sales';
SET my_schema = 'sales_analysis';
SET my_full_schema = $my_db || '.' || $my_schema;
-- Grant usage on the database and schema that will contain the tables and views
GRANT USAGE ON DATABASE IDENTIFIER($my_db) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
-- Grant privileges on future objects within the schema
-- For tables and views, SELECT is the typical "usage" grant for read access
GRANT SELECT ON FUTURE TABLES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT SELECT ON FUTURE VIEWS IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT SELECT ON FUTURE SEMANTIC VIEWS IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
-- For other object types, USAGE is the correct privilege
GRANT USAGE ON FUTURE FUNCTIONS IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON FUTURE PROCEDURES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON FUTURE STAGES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON FUTURE CORTEX SEARCH SERVICES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
-- Grant usage on the database and schema that will contain the tables and views
GRANT USAGE ON DATABASE IDENTIFIER($my_db) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
-- Grant privileges on future objects within the schema
-- For tables and views, SELECT is the typical "usage" grant for read access
GRANT SELECT ON FUTURE TABLES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT SELECT ON FUTURE VIEWS IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT SELECT ON FUTURE SEMANTIC VIEWS IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
-- For other object types, USAGE is the correct privilege
GRANT USAGE ON FUTURE FUNCTIONS IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON FUTURE PROCEDURES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON FUTURE STAGES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
GRANT USAGE ON FUTURE CORTEX SEARCH SERVICES IN SCHEMA IDENTIFIER($my_full_schema) TO ROLE IDENTIFIER($my_role);
示例中包括对未来表和视图的授权,以支持那些用户除了语义视图之外可能需要直接访问底层数据对象的场景。查询语义视图仅需对该语义视图本身拥有 SELECT 权限,但若同时授予对表和视图的访问权限,则可为需要在语义层之外直接查询或分析基础数据的用户提供更大的灵活性。如果希望严格限制用户仅使用语义视图,则可以省略对表和视图的授权,仅授予语义视图对象的权限。但请注意,Cortex Analyst 以及依赖 Cortex Analyst 的 Cortex Agent 要求执行查询的角色拥有对语义视图及其基础表的 SELECT 权限。
在设置授权过程中,请注意以下额外事项:
如果您的最终数据已经正确共享给最终用户,则可以按原计划继续操作。但是,如果您的 Snowflake 数据通常通过服务账户或在 BI 层分享,您需要采取额外的步骤与最终用户共享基础数据。
语义视图是 Snowflake 中的一种新对象类型;因此,大多数角色类型对这些视图没有默认或继承的读/写访问权限。无论底层数据是如何共享的,都应与核心 Snowflake 管理团队协作,为这一新对象类型配置访问权限。
为了 Snowflake Intelligence 的利益(以及未来可能扩展代理功能的潜力),值得在暂存区、存储过程和函数对象上授予 USAGE 权限,如示例所示。您可以利用这些对象在 Snowflake Intelligence 中创建自定义工具。
CREATE SEMANTIC VIEW 是在 Snowsight 中创建或编辑语义视图的任何用户所需的架构级权限。
可使用掩码策略和行访问策略来限制访问。¶
语义视图使用 所有者权限,意味着拥有语义视图访问权限的用户无需单独访问其基础表;访问权限由视图的所有者(角色)控制。只要用户有 SELECT 语义视图对象本身的权限,不需要查看基础数据的权限。此行为与 查询标准视图所需的权限 一致。
根据语义视图和 Cortex Agent 中的基础数据,您可能并不希望所有最终用户都能无限制访问所有数据,即便他们通过自定义角色获得了权限。您可以使用 动态数据掩码策略 和 行访问策略 来在行级别控制对基础数据的访问。这些策略不能直接应用于语义视图的属性,但如果在基础表和列上设置,它们会传播到语义视图并得到强制执行。对于处理敏感数据的应用程序来说,这是一项安全优势。但请注意,作为元数据存储的样本值不会被掩码处理。请参阅 样本值不会被掩码。
例如,您可以创建行访问策略和掩码策略,并将它们同时应用于支撑名为 account_semantic_view 的语义视图的 accounts 表。在此示例中,只有当查询语义视图的用户的电子邮件与授权账户匹配时,相关行才可见。其次,对于未经授权的角色,即使通过语义视图,敏感列 (sensitive_col) 也会被动态掩码。
-- Row access policy (restricts rows by user email)
CREATE OR REPLACE ROW ACCESS POLICY my_schema.account_row_policy AS (user_email STRING)
RETURNS BOOLEAN ->
EXISTS (
SELECT 1
FROM my_schema.account_access_list
WHERE email = user_email()
);
-- Masking policy (masks "sensitive_col" for users without a privileged role)
CREATE OR REPLACE MASKING POLICY my_schema.sensitive_col_masking_policy AS (val STRING)
RETURNS STRING ->
CASE
WHEN current_role() IN ('SENSITIVE_DATA_ACCESS_ROLE') THEN val
ELSE 'MASKED'
END;
-- Attach row access policy to the user_email column in the accounts table
ALTER TABLE my_schema.accounts
ADD ROW ACCESS POLICY account_row_policy ON (user_email);
-- Attach masking policy to the sensitive_col column
ALTER TABLE my_schema.accounts
MODIFY COLUMN sensitive_col
SET MASKING POLICY sensitive_col_masking_policy;
-- Create the semantic view on the "accounts" table
CREATE OR REPLACE SEMANTIC VIEW my_schema.account_semantic_view
TABLES (
accounts AS my_schema.accounts
PRIMARY KEY (account_id)
)
FACTS (
account_id AS accounts.account_id,
account_name AS accounts.account_name
)
DIMENSIONS (
user_email AS accounts.user_email,
sensitive_col AS accounts.sensitive_col
);
如果您使用 dbt,可以在 后钩子 (https://docs.getdbt.com/reference/resource-configs/pre-hook-post-hook) 中应用这些策略。例如:
models:
- name: accounts
description: "Table of accounts for semantic analytics."
columns:
- name: account_id
description: "Unique identifier for the account."
- name: account_name
description: "Name of the account."
- name: user_email
description: "Email address linked to each account row."
- name: sensitive_col
description: "Sensitive information to be masked for non-privileged users."
post-hook:
- >
ALTER TABLE {{ this }}
ADD ROW ACCESS POLICY account_row_policy ON (user_email);
...
代码 ALTER TABLE {{ this }} 使用 dbt 运行时变量来表示完全限定的表名。每次 dbt 构建或更新 accounts 表时,策略都会被应用。
样本值不会被掩码¶
虽然能够查询已应用掩码策略的语义视图的用户在查询结果中看不到实际数据值,但在 Snowsight 中使用 Cortex Analyst 定义的样本值不会被掩码,因为掩码策略不会应用于元数据。运行 GET_DDL 函数时,如果语义视图的维度已定义了样本值,用户将看到这些确切的值。例如,请查看以下 DDL 中 WITHEXTENSION 子句的值:
SELECT GET_DDL('SEMANTIC_VIEW','TEST_SAMPLE_VALUES');
create or replace semantic view TEST_SAMPLE_VALUES
tables (MARCH_TEMPS
...)
facts (MARCH_TEMPS.TEMPERATURE as TEMPERATURE
...)
dimensions (MARCH_TEMPS.CITY as CITY,
MARCH_TEMPS.COUNTY as COUNTY,
MARCH_TEMPS.OBSERVED as OBSERVED)
...
with extension (CA='{"tables":[{"name":"MARCH_TEMPS","dimensions":[{"name":"CITY","sample_values":["South Lake Tahoe","Big Bear City"]},{"name":"COUNTY","sample_values":["San Bernardino","El Dorado"]}],"facts":[{"name":"TEMPERATURE","sample_values":["44","46","52"]}],"time_dimensions":[{"name":"OBSERVED","sample_values":["2025-03-15T09:50:00.000+0000","2025-03-15T09:55:00.000+0000","2025-03-15T10:10:00.000+0000"]}]}
...);
如果需要,在创建视图时,您可以提供具有代表性的非敏感样本值,而无需使用真实值。Cortex Analyst 可以使用任何代表真实值的值来确定列的内容。
用于创建、更新和查询语义视图的选项¶
您可以在 Snowflake 中创建语义视图,方法包括编写 YAML 文件、使用 Snowflake DDL 语法,或在 Snowsight 中使用 UI。Snowflake 提供了便捷的函数,用于导入 YAML 模型以及将语义视图导出为 YAML 模型。 是 Web 令牌 ()、 令牌或 编程访问令牌 将 YAML 语义模型转换为原生语义视图。有关详细信息,请参阅 将 YAML 语义模型转换为原生语义视图。
通常,最好从创建语义视图(而非语义模型)开始。语义视图是 Snowflake 元数据对象,可以利用 RBAC、使用统计信息,并与其他 Snowflake 功能(包括 Cortex Analyst 和 Snowflake Intelligence)直接集成。
要创建语义视图,您有三种主要方式:
在 Snowsight 中创建语义视图:
您可以使用向导,也可以上传 YAML 规范文件。
The wizard approach is recommended for initial setup, and includes automatic creation of synonyms, sample values, and column descriptions. For instructions, see Using Snowsight to create and manage semantic views.
Create a semantic view via a SQL CREATE OR REPLACE SEMANTIC VIEW statement, using any interface that supports SQL. For instructions, see 使用 SQL 命令创建和管理语义视图.
可以通过 JDBC 和 ODBC 驱动程序或 SQLAPI 接口以编程方式创建和查询。但是,您不能使用 Snowflake REST APIs。
您也可以通过调用 SYSTEM$CREATE_SEMANTIC_VIEW_FROM_YAML 存储过程,根据 SQL 中的 YAML 规范创建语义视图。请参阅 将 YAML 语义模型转换为原生语义视图。
此外,如果您使用 dbt,可以通过安装 dbt_semantic_view 包来在 Snowflake 中配置语义视图的创建。有关更多信息,请参阅 与 dbt 项目集成。
请注意,为团队成员设置角色和权限可能会影响他们创建语义视图的能力。例如,如果生产环境要求您以 SERVICE 用户身份运行,则无法在该环境中登录 Snowsight。您必须使用 SQL 命令来创建和管理语义视图。
When semantic views have been created in a Snowflake database, administrators can manage them by using standard SHOW and DESCRIBE commands, and users can access them downstream via SQL SELECT statements and in the following ways:
直接通过 Cortex Analyst 用户界面访问
Through Streamlit or other custom applications that use the Cortex Analyst API and/or generate SELECT FROM SEMANTIC_VIEW statements
通过 Cortex Analyst 使用 Cortex Agents(必须将语义视图添加到新的或现有的 :ref:` 代理 <label_snowflake_agents_modify_agents>` 上)
除注释外,不能在现有语义视图中添加或修改表、列或元数据。因此,如需更改,必须重新创建语义视图(使用 CREATE OR REPLACE 命令)。还需注意,通过 SQL 命令更新语义视图会覆盖您在活动 Snowsight 会话中所做的任何手动编辑。不支持同时保留两种修改。
将 YAML 语义模型转换为原生语义视图¶
您可以使用 SQL 系统函数和存储过程,从 YAML 模型创建语义视图,或从语义视图创建 YAML 模型。
目前 Snowflake 不支持批量转换;必须将 YAML 文件逐个转换为原生语义视图。您可以使用 SYSTEM$CREATE_SEMANTIC_VIEW_FROM_YAML 存储过程进行转换。如果需要批量转换或将其集成到 CI/CD 管道中,则必须按顺序编写转换脚本。Snowflake 近期暂无支持批处理/批量转换的计划。
要将原生语义视图导出回 YAML,可以使用 SYSTEM$READ_YAML_FROM_SEMANTIC_VIEW 函数。该函数可用于自动后处理、双向转换或序列化到版本控制中。
关于规模的相同实用准则适用于原生语义视图和基于 YAML 的模型。有一条实用准则(非硬性限制):为了获得最佳性能,语义视图在所有表中的列总数不应超过 50 至 100 列。该准则适用于原生语义视图和基于 YAML 的模型,主要是因为 AI 组件(如 Cortex Analyst)存在上下文窗口限制。超过该建议可能会导致延迟或质量下降,但这并非技术上的限制。
语义视图的自动部署¶
尽可能利用 CI/CD 管道和编程接口来创建、修改和管理语义视图。理想情况下,应设置工作流程,使语义视图的更新能够自动与 Git 仓库同步。这种方法可以减少因复制粘贴或将更改推送到 Git 而产生的人工操作错误。
将语义视图 YAML(或 SQLDDL)存储在 Git 仓库中;这种方式支持版本控制、同行评审、历史记录和回滚。
如果您正在使用 Snowsight,请定期导出或下载 YAML 模型,并将其提交到 Git。
在 Git 发生变更时触发 CI/CD 管道(执行测试和准确性检查,仅在测试通过后才进行部署)。
如有必要,可通过从 Git 重新部署之前的已知良好状态的 YAML 或 DDL 来回滚。
要将模型从开发环境推广到测试或生产环境,您可以使用自动部署脚本,或者使用 架构级克隆。当包含语义视图的架构被克隆时,语义视图也会被克隆。由于语义视图尚不支持复制,克隆是将语义视图在同一 Snowflake 账户下的不同数据库和环境中迁移的有效替代方案。
可以通过 Snowflake Marketplace 和 数据共享 直接共享语义视图。您可以基于语义视图创建 安全视图,并且支持共享这些嵌套视图。然而,某些重新共享的场景存在限制(例如,当共享的使用者希望进一步共享基于语义视图构建的视图时)。
若要在 Snowflake 数据管道中实现语义视图的物化和维护,可以使用 dbt 项目;详情请参见 与 dbt 项目集成。计划支持使用 Snowflake Terraform 提供程序 实现类似流程。
最终,您的目标应是实现类似于以下 dbt 示例的工作流程:
在 IDE 中处理 dbt 项目的变更,例如 VS 代码。
在 dbt 代码中添加新的语义视图定义。
将更改推送到 Git。
设置在数据管道中执行
'dbt run'操作的触发器。
这样,语义视图将在 Snowflake 账户中被物化。
与 dbt 项目集成¶
您可以通过安装 Snowflake Labs 提供的 dbt_semantic_view 包,将语义视图集成到您的 dbt 工作流程中:https://hub.getdbt.com/Snowflake-Labs/dbt_semantic_view/latest/ (https://hub.getdbt.com/Snowflake-Labs/dbt_semantic_view/latest/)。
此包原生支持 Snowflake 上的 dbt 项目,或者任何能够访问 Snowflake 账户的 dbt 安装环境。您可以使用此包通过 dbt 将语义视图进行物化,并在下游模型中引用这些视图。
备注
Snowflake Labs 中的代码示例仅供参考、测试和学习使用。这些代码示例不受任何服务级别协的约束。
以下说明假设您已经熟悉 dbt,并且在可以连接到 Snowflake 的环境中安装了 dbt。
要安装并使用 dbt_semantic_view 包,请执行如下操作:
将以下代码添加到您的
packages.yml文件中:packages: - package: Snowflake-Labs/dbt_semantic_view version: 1.0.3
请务必包含版本号。包的版本号可能会变动,建议使用最新版本。
运行
dbt deps命令以安装该包。在 dbt 的
models目录下创建一个模型,该模型使用语义视图物化代码:{{ config(materialized='semantic_view') }} TABLES( {{ source('<source_name>', '<table_name>') }}, {{ ref('<another_model>') }} ) [ RELATIONSHIPS ( relationshipDef [ , ... ] ) ] [ FACTS ( semanticExpression [ , ... ] ) ] [ DIMENSIONS ( semanticExpression [ , ... ] ) ] [ METRICS ( semanticExpression [ , ... ] ) ] [ COMMENT = '<comment>' ] [ COPY GRANTS ]
例如,您可以按如下方式物化一个简单的语义视图:
{{ config(materialized='semantic_view') }} TABLES(t1 AS {{ ref('base_table') }}, t2 as {{ source('seed_sources', 'base_table2') }}) DIMENSIONS(t1.count as value, t2.volume as value) METRICS(t1.total_rows AS SUM(t1.count), t2.max_volume as max(t2.volume)) COMMENT='test semantic view'
在 dbt 中配置 Snowflake 连接,并在 dbt 的
profiles.yml文件中指定连接详细信息。更多信息请参阅 `dbt 文档<https://docs.getdbt.com/docs/core/connect-data-platform/profiles.yml>`_。例如:semantic_project: target: snowflake outputs: snowflake: type: "snowflake" account: "{{ env_var('SNOWFLAKE_ACCOUNT') }}" user: "{{ env_var('SNOWFLAKE_USER') }}" password: "{{ env_var('SNOWFLAKE_PASSWORD') }}" authenticator: "{{ env_var('SNOWFLAKE_AUTHENTICATOR') }}" role: "{{ env_var('SNOWFLAKE_ROLE') }}" database: "{{ env_var('SNOWFLAKE_DATABASE') }}" warehouse: "{{ env_var('SNOWFLAKE_WAREHOUSE') }}" schema: "{{ env_var('SNOWFLAKE_SCHEMA') }}" threads: 4
根据此配置文件,您可以使用以下环境变量进行身份验证:
$ export SNOWFLAKE_ACCOUNT=snowflake_acct1 $ export SNOWFLAKE_USER=sem_user1 $ export SNOWFLAKE_PASSWORD=************** $ export SNOWFLAKE_AUTHENTICATOR=externalbrowser $ export SNOWFLAKE_ROLE=semantic_role $ export SNOWFLAKE_DATABASE=sem_db $ export SNOWFLAKE_WAREHOUSE=sem_wh $ export SNOWFLAKE_SCHEMA=sem_schema
运行
dbt build命令以连接到您的 Snowflake 账户并创建模型。以下示例构建了一个名为models/semantic_view_basic的特定模型。请注意,另一个模型table_refer_to_semantic_view依赖于此模型,因此该命令在末尾需要加上+标志。$ dbt build --target snowflake --select semantic_view_basic+ 23:43:16 Running with dbt=1.11.0-b3 23:43:17 Registered adapter: snowflake=1.10.2 23:43:17 Found 9 models, 8 data tests, 1 seed, 2 operations, 2 sources, 500 macros 23:43:17 23:43:17 Concurrency: 4 threads (target='snowflake') 23:43:17 23:43:32 1 of 2 START hook: dbt_semantic_view_integration_tests.on-run-start.0 .......... [RUN] 23:43:32 1 of 2 OK hook: dbt_semantic_view_integration_tests.on-run-start.0 ............. [OK in 0.90s] 23:43:33 2 of 2 START hook: dbt_semantic_view_integration_tests.on-run-start.1 .......... [RUN] 23:43:33 2 of 2 OK hook: dbt_semantic_view_integration_tests.on-run-start.1 ............. [OK in 0.38s] 23:43:33 23:43:33 1 of 6 START sql semantic_view model sem_schema.semantic_view_basic ............ [RUN] 23:43:33 1 of 6 OK created sql semantic_view model sem_schema.semantic_view_basic ....... [SUCCESS 1 in 0.26s] 23:43:33 3 of 6 START test semantic_view_basic_has_no_copy_grants ....................... [RUN] 23:43:33 2 of 6 START test semantic_view_basic_has_comment .............................. [RUN] 23:43:33 4 of 6 START test semantic_view_sum_matches_base_table ......................... [RUN] 23:43:33 2 of 6 PASS semantic_view_basic_has_comment .................................... [PASS in 0.23s] 23:43:34 3 of 6 PASS semantic_view_basic_has_no_copy_grants ............................. [PASS in 0.75s] 23:43:34 4 of 6 PASS semantic_view_sum_matches_base_table ............................... [PASS in 1.05s] 23:43:34 5 of 6 START sql table model sem_schema.table_refer_to_semantic_view ........... [RUN] 23:43:35 5 of 6 OK created sql table model sem_schema.table_refer_to_semantic_view ...... [SUCCESS 1 in 1.22s] 23:43:35 6 of 6 START test table_refer_semantic_view_matches_semantic_view .............. [RUN] 23:43:36 6 of 6 PASS table_refer_semantic_view_matches_semantic_view .................... [PASS in 0.26s] 23:43:36 23:43:36 Finished running 2 project hooks, 1 semantic view model, 1 table model, 4 data tests in 0 hours 0 minutes and 19.34 seconds (19.34s). 23:43:36 23:43:36 Completed successfully 23:43:36 23:43:36 Done. PASS=8 WARN=0 ERROR=0 SKIP=0 NO-OP=0 TOTAL=8
有关 dbt_semantic_view 包的更多信息(其中包含可运行的预构建模型和测试),请参阅 README.md 文件。访问 https://hub.getdbt.com/Snowflake-Labs/dbt_semantic_view/latest/ (https://hub.getdbt.com/Snowflake-Labs/dbt_semantic_view/latest/) 并选择 View on GitHub。
另请参阅 https://www.snowflake.cn/en/engineering-blog/dbt-semantic-view-package/。
与 BI 工具集成¶
一些 BI 工具供应商提供与 Snowflake 语义视图的集成。如需了解更多关于这些集成的信息,请联系您的 BI 工具账户团队,并访问以下链接:
Sigma:https://www.sigmacomputing.com/blog/snowflake-semantic-views-launch (https://www.sigmacomputing.com/blog/snowflake-semantic-views-launch)
Omni:https://omni.co/snowflake (https://omni.co/snowflake)
Honeydew:https://honeydew.ai/blog/honeydew-and-snowflake-semantic-views/ (https://honeydew.ai/blog/honeydew-and-snowflake-semantic-views/)
Hex:https://hex.tech/blog/introducing-snowflake-semantic-sync-aisql/ (https://hex.tech/blog/introducing-snowflake-semantic-sync-aisql/)