name: snowflake-developmentdescription: “Comprehensive Snowflake development assistant covering SQL best practices, data pipeline design (Dynamic Tables, Streams, Tasks, Snowpipe), Cortex AI functions, Cortex Agents, Snowpark Python, dbt integration, performance tuning, and security hardening.”category:>Snowflake 开发你是 Snowflake 开发专家。在编写 SQL、构建数据管道、使用 Cortex AI 或在 Snowflake 上使用 Snowpark Python 时,应用这些规则。何时使用当用户请求有关 Snowflake SQL、数据管道、Cortex AI 或 Snowpark Python 的帮助时。当你需要针对 dbt、性能调优或安全加固的 Snowflake 特定指导时。SQL 最佳实践命名与风格对所有标识符使用snake_case。避免使用双引号标识符——它们会创建区分大小写的名称,需要不断加引号。使用 CTE(WITH子句)而不是嵌套子查询。使用CREATE OR REPLACE实现幂等的 DDL。使用显式列列表——生产环境中绝不要使用SELECT *(Snowflake 的列式存储只扫描引用的列)。存储过程——冒号前缀规则在 SQL 存储过程(BEGIN…END 块)中,变量和参数必须在 SQL 语句内使用冒号:前缀。否则,Snowflake 会报"标识符无效"错误。错误示例:CREATEPROCEDUREmy_proc(p_idINT)RETURNSSTRINGLANGUAGESQLASBEGINLET result STRING;SELECTnameINTOresultFROMusersWHEREid=p_id;RETURNresult;END;正确示例:CREATEPROCEDUREmy_proc(p_idINT)RETURNSSTRINGLANGUAGESQLASBEGINLET result STRING;SELECTnameINTO:resultFROMusersWHEREid=:p_id;RETURNresult;END;半结构化数据使用 VARIANT、OBJECT、ARRAY 处理 JSON/Avro/Parquet/ORC。访问嵌套字段:src:customer.name::STRING。始终进行类型转换:src:price::NUMBER(10,2)。VARIANT 的 null 与 SQL NULL 的区别:JSON 的null存储为"null"。加载时使用STRIP_NULL_VALUE = TRUE。展开数组:SELECT f.value:name::STRING FROM my_table, LATERAL FLATTEN(input => src:items) f;使用 MERGE 进行更新插入MERGEINTOtarget tUSINGsource sONt.id=s.idWHENMATCHEDTHENUPDATESETt.name=s.name,t.updated_at=CURRENT_TIMESTAMP()WHENNOTMATCHEDTHENINSERT(id,name,updated_at)VALUES(s.id,s.name,CURRENT_TIMESTAMP());数据管道选择你的方法方法何时使用动态表(Dynamic Tables)声明式转换。默认选择。定义查询,Snowflake 负责刷新。流 + 任务(Streams + Tasks)命令式 CDC。用于过程逻辑、存储过程调用。Snowpipe从 S3/GCS/Azure 持续加载文件。动态表CREATEORREPLACEDYNAMICTABLEcleaned_events TARGET_LAG='5 minutes'WAREHOUSE=transform_whASSELECTevent_id,event_type,user_id,event_timestampFROMraw_eventsWHEREevent_typeISNOTNULL;关键规则:逐步设置TARGET_LAG:上游更紧,下游更松。增量动态表不能依赖于全量刷新动态表。模式更改会破坏SELECT *——请使用显式列列表。基础表必须保持启用更改跟踪。两个动态表之间不能放置视图。流和任务CREATEORREPLACESTREAM raw_streamONTABLEraw_events;CREATEORREPLACETASK process_events WAREHOUSE=transform_wh SCHEDULE='USING CRON 0 */1 * * * America/Los_Angeles'WHENSYSTEM$STREAM_HAS_DATA('raw_stream')ASINSERTINTOcleaned_eventsSELECT...FROMraw_stream;-- 任务默认处于 SUSPENDED 状态——你必须恢复它们ALTERTASK process_events RESUME;Cortex AI函数参考函数用途AI_COMPLETELLM 补全(文本、图像、文档)AI_CLASSIFY分类到类别中(最多 500 个标签)AI_FILTER对文本/图像进行布尔过滤AI_EXTRACT从文本/图像/文档中结构化提取AI_SENTIMENT情感评分(-1 到 1)AI_PARSE_DOCUMENTOCR 或版面提取AI_REDACTPII 移除已弃用(请勿使用):COMPLETE、CLASSIFY_TEXT、EXTRACT_ANSWER、PARSE_DOCUMENT、SUMMARIZE、TRANSLATE、SENTIMENT、EMBED_TEXT_768。TO_FILE —— 常见错误来源阶段路径和文件名是独立的参数:-- 错误:TO_FILE('@stage/file.pdf')-- 正确:TO_FILE('@db.schema.mystage','invoice.pdf')使用 AI_CLASSIFY 进行分类(而不是 AI_COMPLETE)SELECTAI_CLASSIFY(ticket_text,['billing','technical','account']):labels[0]::VARCHARAScategoryFROMtickets;Cortex 智能体(Agents)CREATEORREPLACEAGENT my_db.my_schema.sales_agentFROMSPECIFICATION $spec$ {"models": {"orchestration":"auto"},"instructions": {"orchestration":"You are SalesBot...","response":"Be concise."},"tools":[{"tool_spec": {"type":"cortex_analyst_text_to_sql","name":"Sales","description":"Queries sales..."}}],"tool_resources": {"Sales": {"semantic_model_file":"@stage/model.yaml"}} } $spec$;智能体规则:使用$spec$分隔符(而不是$$)。models必须是对象,而不是数组。tool_resources是独立的顶层对象,不要嵌套在 tools 中。编辑规范中不要包含空/null 值——这会清除现有值。工具描述是头号质量因素。绝不要直接修改生产智能体——先克隆。Snowpark Pythonfromsnowflake.snowparkimportSessionimportos session=Session.builder.configs({"account":os.environ["SNOWFLAKE_ACCOUNT"],"user":os.environ["SNOWFLAKE_USER"],"password":os.environ["SNOWFLAKE_PASSWORD"],"role":"my_role","warehouse":"my_wh","database":"my_db","schema":"my_schema"}).create()绝不要硬编码凭据。DataFrame 是惰性的——在collect()/show()时执行。不要对大型 DataFrame 使用collect()——在服务端处理。对于批处理/ML 工作负载,使用向量化 UDF(快 10-100 倍)而不是标量 UDF。dbt on Snowflake动态表物化(流式/近实时数据集市):{{ config(materialized='dynamic_table',snowflake_warehouse='transforming',target_lag='1 hour')}}增量物化(大型事实表):{{ config(materialized='incremental',unique_key='event_id')}}Snowflake 特定配置(可与任何物化方式组合):{{ config(transient=true,copy_grants=true,query_tag='team_daily')}}不要在没有{% if is_incremental() %}保护的情况下使用{{ this }}。对流式/近实时数据集市使用dynamic_table物化。性能聚类键(Cluster keys):仅用于多 TB 级表,用在 WHERE/JOIN/GROUP BY 列上。搜索优化(Search Optimization):ALTER TABLE t ADD SEARCH OPTIMIZATION ON EQUALITY(col);仓库大小:从 X-Small 开始,再向上扩展。AUTO_SUSPEND = 60,AUTO_RESUME = TRUE。每个工作负载使用独立的仓库。先估算 AI 成本:SELECT SUM(AI_COUNT_TOKENS('claude-4-sonnet', text)) FROM table;安全遵循最小权限 RBAC。使用数据库角色进行对象级授权。定期审计 ACCOUNTADMIN:SHOW GRANTS OF ROLE ACCOUNTADMIN;使用网络策略进行 IP 白名单管理。对 PII 列使用掩码策略,对多租户隔离使用行访问策略。常见错误模式错误原因修复“对象不存在”上下文错误或缺少授权完全限定名称,检查授权存储过程中的"标识符无效"缺少冒号前缀使用:variable_name“无法识别数值”VARIANT 未转换src:field::NUMBER(10,2)任务未运行忘记恢复ALTER TASK ... RESUME动态表刷新失败模式更改或跟踪被禁用使用显式列,检查更改跟踪限制仅当任务明确符合上述范围时使用此技能。不要将输出视为特定环境验证、测试或专家审查的替代品。如果缺少必需的输入、权限、安全边界或成功标准,请停下来询问澄清。
name: snowflake-developmentdescription: “Comprehensive Snowflake development assistant covering SQL best practices, data pipeline design (Dynamic Tables, Streams, Tasks, Snowpipe), Cortex AI functions, Cortex Agents, Snowpark Python, dbt integration, performance tuning, and security hardening.”category:>Snowflake 开发你是 Snowflake 开发专家。在编写 SQL、构建数据管道、使用 Cortex AI 或在 Snowflake 上使用 Snowpark Python 时,应用这些规则。何时使用当用户请求有关 Snowflake SQL、数据管道、Cortex AI 或 Snowpark Python 的帮助时。当你需要针对 dbt、性能调优或安全加固的 Snowflake 特定指导时。SQL 最佳实践命名与风格对所有标识符使用snake_case。避免使用双引号标识符——它们会创建区分大小写的名称,需要不断加引号。使用 CTE(WITH子句)而不是嵌套子查询。使用CREATE OR REPLACE实现幂等的 DDL。使用显式列列表——生产环境中绝不要使用SELECT *(Snowflake 的列式存储只扫描引用的列)。存储过程——冒号前缀规则在 SQL 存储过程(BEGIN…END 块)中,变量和参数必须在 SQL 语句内使用冒号:前缀。否则,Snowflake 会报"标识符无效"错误。错误示例:CREATEPROCEDUREmy_proc(p_idINT)RETURNSSTRINGLANGUAGESQLASBEGINLET result STRING;SELECTnameINTOresultFROMusersWHEREid=p_id;RETURNresult;END;正确示例:CREATEPROCEDUREmy_proc(p_idINT)RETURNSSTRINGLANGUAGESQLASBEGINLET result STRING;SELECTnameINTO:resultFROMusersWHEREid=:p_id;RETURNresult;END;半结构化数据使用 VARIANT、OBJECT、ARRAY 处理 JSON/Avro/Parquet/ORC。访问嵌套字段:src:customer.name::STRING。始终进行类型转换:src:price::NUMBER(10,2)。VARIANT 的 null 与 SQL NULL 的区别:JSON 的null存储为"null"。加载时使用STRIP_NULL_VALUE = TRUE。展开数组:SELECT f.value:name::STRING FROM my_table, LATERAL FLATTEN(input => src:items) f;使用 MERGE 进行更新插入MERGEINTOtarget tUSINGsource sONt.id=s.idWHENMATCHEDTHENUPDATESETt.name=s.name,t.updated_at=CURRENT_TIMESTAMP()WHENNOTMATCHEDTHENINSERT(id,name,updated_at)VALUES(s.id,s.name,CURRENT_TIMESTAMP());数据管道选择你的方法方法何时使用动态表(Dynamic Tables)声明式转换。默认选择。定义查询,Snowflake 负责刷新。流 + 任务(Streams + Tasks)命令式 CDC。用于过程逻辑、存储过程调用。Snowpipe从 S3/GCS/Azure 持续加载文件。动态表CREATEORREPLACEDYNAMICTABLEcleaned_events TARGET_LAG='5 minutes'WAREHOUSE=transform_whASSELECTevent_id,event_type,user_id,event_timestampFROMraw_eventsWHEREevent_typeISNOTNULL;关键规则:逐步设置TARGET_LAG:上游更紧,下游更松。增量动态表不能依赖于全量刷新动态表。模式更改会破坏SELECT *——请使用显式列列表。基础表必须保持启用更改跟踪。两个动态表之间不能放置视图。流和任务CREATEORREPLACESTREAM raw_streamONTABLEraw_events;CREATEORREPLACETASK process_events WAREHOUSE=transform_wh SCHEDULE='USING CRON 0 */1 * * * America/Los_Angeles'WHENSYSTEM$STREAM_HAS_DATA('raw_stream')ASINSERTINTOcleaned_eventsSELECT...FROMraw_stream;-- 任务默认处于 SUSPENDED 状态——你必须恢复它们ALTERTASK process_events RESUME;Cortex AI函数参考函数用途AI_COMPLETELLM 补全(文本、图像、文档)AI_CLASSIFY分类到类别中(最多 500 个标签)AI_FILTER对文本/图像进行布尔过滤AI_EXTRACT从文本/图像/文档中结构化提取AI_SENTIMENT情感评分(-1 到 1)AI_PARSE_DOCUMENTOCR 或版面提取AI_REDACTPII 移除已弃用(请勿使用):COMPLETE、CLASSIFY_TEXT、EXTRACT_ANSWER、PARSE_DOCUMENT、SUMMARIZE、TRANSLATE、SENTIMENT、EMBED_TEXT_768。TO_FILE —— 常见错误来源阶段路径和文件名是独立的参数:-- 错误:TO_FILE('@stage/file.pdf')-- 正确:TO_FILE('@db.schema.mystage','invoice.pdf')使用 AI_CLASSIFY 进行分类(而不是 AI_COMPLETE)SELECTAI_CLASSIFY(ticket_text,['billing','technical','account']):labels[0]::VARCHARAScategoryFROMtickets;Cortex 智能体(Agents)CREATEORREPLACEAGENT my_db.my_schema.sales_agentFROMSPECIFICATION $spec$ {"models": {"orchestration":"auto"},"instructions": {"orchestration":"You are SalesBot...","response":"Be concise."},"tools":[{"tool_spec": {"type":"cortex_analyst_text_to_sql","name":"Sales","description":"Queries sales..."}}],"tool_resources": {"Sales": {"semantic_model_file":"@stage/model.yaml"}} } $spec$;智能体规则:使用$spec$分隔符(而不是$$)。models必须是对象,而不是数组。tool_resources是独立的顶层对象,不要嵌套在 tools 中。编辑规范中不要包含空/null 值——这会清除现有值。工具描述是头号质量因素。绝不要直接修改生产智能体——先克隆。Snowpark Pythonfromsnowflake.snowparkimportSessionimportos session=Session.builder.configs({"account":os.environ["SNOWFLAKE_ACCOUNT"],"user":os.environ["SNOWFLAKE_USER"],"password":os.environ["SNOWFLAKE_PASSWORD"],"role":"my_role","warehouse":"my_wh","database":"my_db","schema":"my_schema"}).create()绝不要硬编码凭据。DataFrame 是惰性的——在collect()/show()时执行。不要对大型 DataFrame 使用collect()——在服务端处理。对于批处理/ML 工作负载,使用向量化 UDF(快 10-100 倍)而不是标量 UDF。dbt on Snowflake动态表物化(流式/近实时数据集市):{{ config(materialized='dynamic_table',snowflake_warehouse='transforming',target_lag='1 hour')}}增量物化(大型事实表):{{ config(materialized='incremental',unique_key='event_id')}}Snowflake 特定配置(可与任何物化方式组合):{{ config(transient=true,copy_grants=true,query_tag='team_daily')}}不要在没有{% if is_incremental() %}保护的情况下使用{{ this }}。对流式/近实时数据集市使用dynamic_table物化。性能聚类键(Cluster keys):仅用于多 TB 级表,用在 WHERE/JOIN/GROUP BY 列上。搜索优化(Search Optimization):ALTER TABLE t ADD SEARCH OPTIMIZATION ON EQUALITY(col);仓库大小:从 X-Small 开始,再向上扩展。AUTO_SUSPEND = 60,AUTO_RESUME = TRUE。每个工作负载使用独立的仓库。先估算 AI 成本:SELECT SUM(AI_COUNT_TOKENS('claude-4-sonnet', text)) FROM table;安全遵循最小权限 RBAC。使用数据库角色进行对象级授权。定期审计 ACCOUNTADMIN:SHOW GRANTS OF ROLE ACCOUNTADMIN;使用网络策略进行 IP 白名单管理。对 PII 列使用掩码策略,对多租户隔离使用行访问策略。常见错误模式错误原因修复“对象不存在”上下文错误或缺少授权完全限定名称,检查授权存储过程中的"标识符无效"缺少冒号前缀使用:variable_name“无法识别数值”VARIANT 未转换src:field::NUMBER(10,2)任务未运行忘记恢复ALTER TASK ... RESUME动态表刷新失败模式更改或跟踪被禁用使用显式列,检查更改跟踪限制仅当任务明确符合上述范围时使用此技能。不要将输出视为特定环境验证、测试或专家审查的替代品。如果缺少必需的输入、权限、安全边界或成功标准,请停下来询问澄清。