如何把 SPL 集成到自己的 snowflake 环境中

1. 前 言

在 snowflake 云环境下,用户可搭建集算器 SPL 应用程序包开发环境、生成 App 安装包。用户安装 App 后,通过 SPL 函数接口调用集算器进行数据运算,将计算结果返回给用户。用户不仅可以访问表数据、文件数据、可执行脚本等资源,还可以访问 aws S3、azure、google gcs 等云资源。

2.Native App Framework

参考:https://docs.snowflake.com/en/developer-guide/native-apps/native-apps-about
在 Snowflake Native App Framework 环境下,将集算器 SPL 集成到 snowflake,生成、测试、使用 SPL 接口,并生成 App 安装包,方便用户在消费端安装使用。
下面以生成应用程序包 myspl_package 为例说明如何实现 SPL 集成的。

2.1 创建应用程序包

在 snowsight 或工具 snowsql 环境下执行脚本操作:
GRANT CREATE APPLICATION PACKAGE ON ACCOUNT TO ROLE accountadmin;
CREATE APPLICATION PACKAGE myspl_package;
USE APPLICATION PACKAGE myspl_package;
CREATE SCHEMA myspl_stage;
CREATE OR REPLACE STAGE myspl_package.myspl_stage.spl_stage
  FILE_FORMAT = (TYPE = 'csv' FIELD_DELIMITER = '|' SKIP_HEADER = 1);

myspl_package 是生成 SPL 接口的开发环境。

100png

2.2 增加数据表

use schema myspl_package.public;
CREATE TABLE IF NOT EXISTS accounts (ID INT, NAME VARCHAR, VALUE VARCHAR);
INSERT INTO accounts VALUES
  (2, 'Frank', 'Snowflake'),
  (3, 'Benoit', 'Snowflake'),
  (4, 'Steven', 'Acme');

2.3 脚本 setupspl.sql

App 制作脚本 setupspl.sql 中定义了 SPL 接口、依赖 jar 包,接口授权等。
/********** application start *******************/
CREATE APPLICATION ROLE app_public;
CREATE OR ALTER VERSIONED SCHEMA myschema;
GRANT USAGE ON SCHEMA myschema TO APPLICATION ROLE app_public;

/********** to java spl *******************/
CREATE OR REPLACE PROCEDURE myschema.runSPL (spl VARCHAR)
RETURNS TABLE()
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES = ('com.snowflake:snowpark:latest')
IMPORTS = ('/java/esproc-bin-new.jar',
                                    '/java/spl-java-func.jar',
                                    '/java/bcpkix-jdk18on-1.75.jar',
                                    '/java/bcprov-jdk18on-1.75.jar',
                                    '/java/snowflake-jdbc-3.14.1.jar',
                                    '/java/lz4-1.3.0.jar',
                                    '/java/fastjson-1.2.28.jar')
HANDLER = 'com.scudata.lib.snowflake.PlusProcedure.run';

GRANT USAGE ON PROCEDURE myschema.runSPL (VARCHAR) TO APPLICATION ROLE app_public;
/********** to java spl2 *******************/
CREATE OR REPLACE PROCEDURE myschema.runSPL (spl VARCHAR, required_arg variant)
RETURNS TABLE()
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES = ('com.snowflake:snowpark:latest')
IMPORTS = ('/java/esproc-bin-new.jar',
                                    '/java/spl-java-func.jar',
                                    '/java/bcpkix-jdk18on-1.75.jar',
                                    '/java/bcprov-jdk18on-1.75.jar',
                                    '/java/snowflake-jdbc-3.14.1.jar',
                                    '/java/lz4-1.3.0.jar',
                                    '/java/fastjson-1.2.28.jar')
HANDLER = 'com.scudata.lib.snowflake.PlusProcedure.run';

GRANT USAGE ON PROCEDURE myschema.runSPL (VARCHAR, variant) TO APPLICATION ROLE app_public;

/********** to java spl3 *******************/
CREATE OR REPLACE function myschema.runUdf (spl VARCHAR)
RETURNS VARIANT
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES = ('com.snowflake:snowpark:latest')
IMPORTS = ('/java/esproc-bin-new.jar',
                                    '/java/spl-java-func.jar',
                                    '/java/bcpkix-jdk18on-1.75.jar',
                                    '/java/bcprov-jdk18on-1.75.jar',
                                    '/java/snowflake-jdbc-3.14.1.jar',
                                    '/java/lz4-1.3.0.jar',
                                    '/java/fastjson-1.2.28.jar')
HANDLER = 'com.scudata.lib.snowflake.PlusScudata.calculate';
GRANT USAGE ON function myschema.runUdf(VARCHAR) TO APPLICATION ROLE app_public;
 
/********** to java spl4 *******************/
CREATE OR REPLACE function myschema.runUdf (spl VARCHAR, argv variant)
RETURNS VARIANT
LANGUAGE JAVA
RUNTIME_VERSION = '11'
PACKAGES = ('com.snowflake:snowpark:latest')
IMPORTS = ('/java/esproc-bin-new.jar',
                                    '/java/spl-java-func.jar',
                                    '/java/bcpkix-jdk18on-1.75.jar',
                                    '/java/bcprov-jdk18on-1.75.jar',
                                    '/java/snowflake-jdbc-3.14.1.jar',
                                    '/java/lz4-1.3.0.jar',
                                    '/java/fastjson-1.2.28.jar')
HANDLER = 'com.scudata.lib.snowflake.PlusScudata.calculate';
GRANT USAGE ON function myschema.runUdf (VARCHAR, variant) TO APPLICATION ROLE app_public;
 
在 myschema 下定义两个接口 runSPL 和 runUDF,类型分别是 procedure 与 function,其中接口与 SPL java 关联程序放在 spl-java-func.jar。
setupspl.sql 脚本内容根据需要可进行增减处理。

2.4 上传文件

参考 Native App Framework 对生成 App 应用的要求,下面列出 App 生成所依赖的文件目录结构,上传云平台后这些目录结构保持相对不变。这些文件资源存放在 splShell 文件夹下,打包成 splShell.zip 当作本篇文章的附件,需要的可下载。用于制作 App 的目录及文件如下:
splShell
              manifest.yml
              readme.md
splShell/java
                     bcpkix-jdk18on-1.75.jar
                     bcprov-jdk18on-1.75.jar
                     esproc-bin-new.jar
                     fastjson-1.2.28.jar
                     lz4-1.3.0.jar
                     snowflake-jdbc-3.14.1.jar
                     spl-java-func.jar
splShell/scripts

                     setupspl.sql
// 自定义 SPL 脚本、数据文件位置
splShell/splx
                     vmTable.splx
                     query.splx
                     car_sales.json
 
除了 lz4-1.3.0.jar, esproc-bin-xxx.jar 与 snowflake-jdbc-xxx.jar 外,其它 yml, jar, splx 等文件都在 splShell.zip 中,解压 zip 文件基本就能还原上述文件目录结构。
 
其中 manifest.yml 放在 splShell.zip 文件的 splShell 目录中,作为 App 应用的入口,定义了所需要的安装脚本 scripts/setupspl.sql。
SPL 接口所依赖的 jar 文件放入 splShell. zip 文件的 splShell/java 目录中。
lz4-1.3.0.jar, esproc-bin-xxx.jar :从 SPL 官网 下载 ,从 esproc 安装包里提取。
snowflake-jdbc-xxx.jar :从 snowflake 官网 下载

在工具 snowsql(使用参考附录) 下上传 jar 包,测试数据文件、脚本等资源到 stage: @myspl_package.myspl_stage.spl_stage 下。
PUT file://D:/splShell/manifest.yml @myspl_package.myspl_stage.spl_stage overwrite=true auto_compress=false;
PUT file://D:/splShell/readme.md @myspl_package.myspl_stage.spl_stage overwrite=true auto_compress=false;
PUT file://D:/splShell/java/*.jar @myspl_package.myspl_stage.spl_stage/java overwrite=true auto_compress=false;

PUT file://D:/splShell/scripts/setupspl.sql @myspl_package.myspl_stage.spl_stage /scripts overwrite=true auto_compress=false;
 
测试所用的脚本、数据。
PUT file://D:/splShell/splx/vmTable.splx @myspl_package.myspl_stage.spl_stage/splx overwrite=true auto_compress=false;
PUT file:// D:/splShell/splx/query.runUDF @myspl_package.myspl_stage.spl_stage/splx overwrite=true auto_compress=false;
PUT file:// D:/splShell/splx/car_sales.json @myspl_package.myspl_stage.spl_stage/splx overwrite=true auto_compress=false;

101png

2.5 生成 App

定义的 SPL 接口通过应用程序包生成 App。
DROP APPLICATION myspl_app; (若存在 myspl_app 则执行此句,否则跳过)
CREATE APPLICATION myspl_app
FROM APPLICATION PACKAGE myspl_package
USING '@myspl_package.myspl_stage.spl_stage';
运行时调用脚本 setupspl.sql,执行有异常则会显示出错误提示,改错后再执行;执行成功后,可在 databases->myspl_app->myschema 下看到 SPL 接口 runSPL, runUDF。

102png

2.6 授权 App

测试前将所需要数据表及文件授权给 App, SPL 接口才能正常访问。
GRANT USAGE ON DATABASE myspl_package to APPLICATION myspl_app;
GRANT USAGE ON SCHEMA myspl_stage to APPLICATION myspl_app;
GRANT READ,WRITE ON STAGE myspl_stage.spl_stage to APPLICATION myspl_app;
 
GRANT USAGE ON SCHEMA public to APPLICATION myspl_app;
GRANT SELECT ON TABLE public.accounts TO APPLICATION myspl_app;

2.7 简单测试接口

测试 SPL 接口调用是否能正常运行。

A、 runUDF 测试: 在 sql 语句中以函数方式调用。
select myspl_app.myschema.runUDF('=?.(~.array().sum())',[[1,2,3],[2,3,4],[5,6,9]]) as vals;

103png


B、runSPL 测试: 以存储过程方式调用。
call myspl_app.myschema.runSPL('@MYDB.PUBLIC.MYSTAGE/vmTable.splx');

104png


在开发阶段,若在云平台下调用 SPL 接口失败,返回日志中没有具体的异常原因及 java 程序日志输出,跟踪比较麻烦。snowflake 提供了事件表机制来记录执行中的输出日志 (参考附录)。

3. 生成 App 安装包

集算器 App 安装包在 snowflake MarketPlace 中发布,可供用户下载、安装及使用,制作安装包时需要有 App 发布版本号。

3.1 生成发布版本号

ALTER APPLICATION PACKAGE myspl_package ADD VERSION v1_0 USING '@myspl_package.myspl_stage.spl_stage';
 
ALTER APPLICATION PACKAGE myspl_package SET DEFAULT RELEASE DIRECTIVE
  VERSION = v1_0
  PATCH = 0;
SHOW RELEASE DIRECTIVES IN APPLICATION PACKAGE myspl_package;
也可在 Projects->App Packages 查看应用程序包发布版本号:

105png

3.2 生成安装包

在 Data Products->Provider Studio->Listings 下生成 SPL App 安装包。
106png


填写 App 名称: myAppSpl
107png
由于是内部版测试,选择选项 Only Specified Consumers
 
选择 package:myspl_package

108png


109png


填写消费帐号后,点击“publish”返回发布包列表如下:

110png

3.3 维护发布包

对于 java 程序或 setupspl.sql 脚本有改动,则需要操作步骤如下:
1、java 程序变更,则需要更新 spl-java-func.jar 包。
2、依赖 jar 包变化则需要修改 setupspl.sql 定义接口的依赖库。
3、上传变动文件 (jar, setupspl.sql 等) 到 stage 下对应的目录。
4、重新生成 App 应用:
DROP APPLICATION myspl_app;
CREATE APPLICATION myspl_app;
FROM APPLICATION PACKAGE myspl_package
USING '@myspl_package.myspl_stage.spl_stage';
5、对执行步骤 4 反馈问题,根据反馈日志分析后再修改,测试 SPL 接口,直到解决问题为止。(若无问题可跳过此步)
6、重新生成 app 安装包前需要变更版本号,否则再次生成的安装包还是以前的而不是变动后的。
  ALTER APPLICATION PACKAGE myspl_package DROP VERSION v2_0;
  ALTER APPLICATION PACKAGE myspl_package
  ADD VERSION v2_0 USING '@myspl_package.myspl_stage.spl_stage';
  ALTER APPLICATION PACKAGE myspl_package SET DEFAULT RELEASE DIRECTIVE
  VERSION = v2_0
  PATCH = 0;
7、参考 3.2 重新生成 App 安装包。


管理员使用 snowsql 或 sql worksheet 生成应用程序包,上传定义接口所需要的 jar, 脚本、文件等资源,测试 SPL 接口正常后生成 App 安装包。

4.安装 App

若用户希望能快速使用 SPL 接口,则安装 myAppSpl 包就可以,授权表数据及 stage 给 SPL 接口所在应用 myAppSpl,然后就可以调用 SPL 接口。现以 consumer 帐号登陆 snowflake 云平台、角色为 accountAdmin 为例说明。

在 Data Products->Marketplace 页面,找到安装包 myAppSpl

111png


或直接在导航栏 Apps 下可看到 myAppSpl.

112png


点击”Get”按钮安装

113png


warehouse 项选择 SPL_DEMO 后点击”Get”, 等安装完成后返回安装 Apps 列表:

114png

在 Data->Databases->myAppSpl->myschema 中可以看到 function: runUDF 与 Procedure: runSPL 接口

115png

5. 创建数据库

尽管 myAppSpl 应用中包括 SPL 接口 runUDF、runSPL, 但由于其库为只读模式,不能存放表数据、脚本、文件等资源,访问的数据则需要其它数据库提供。
 
以新建数据库、数据表、存放 splx 脚本、数据文件等操作为事例说明。

5.1 新建数据库

在 Data->Database 下新建数据库;

120png
输入数据库名称:mydb。

121png


也可以在 SQL WorkSheet 下运行 create database mydb;
缺省会生成一个名为 public 的 schema。

5.2 创建 stage

在 SQL WorkSheet 下,指定当前位置 mydb.public 后操作,

122png


CREATE OR REPLACE STAGE mydb.public.mystage
  FILE_FORMAT = (TYPE = 'csv' FIELD_DELIMITER = '|' SKIP_HEADER = 1);

123png


 
给 mystage 选择一个 warehouse, 如 SPL_DEMO。

124png

5.3 上传文件

将上传文件存储到 mydb.public.mystage。

125png


 
通过 Files 按钮可上传文件:

126png


将本地脚本文件 vmTable.splx 上传,内容为:

A

B

1

=create(Athlete,Event,age)

2

>A1.insert(0,70:age,"s1":Athlete,"Vault":Event)

3

>A1.insert(0:2,70+#:age,"s2"+string(#):Athlete,"Floor":Event)

4

return A1

拖拽到上传页面,点击upload”按钮上传。

5.4 新建表数据

use SCHEMA mydb.public;
CREATE OR REPLACE TABLE sample_product_data (id INT, parent_id INT, category_id INT, name VARCHAR, serial_number VARCHAR, key INT, "3rd" INT);
INSERT INTO sample_product_data VALUES
    (1, 0, 5, 'Product 1', 'prod-1', 1, 10),
    (2, 1, 5, 'Product 1A', 'prod-1-A', 1, 20),
    (3, 1, 5, 'Product 1B', 'prod-1-B', 1, 30),
    (4, 0, 10, 'Product 2', 'prod-2', 2, 40),
    (5, 4, 10, 'Product 2A', 'prod-2-A', 2, 50),
    (6, 4, 10, 'Product 2B', 'prod-2-B', 2, 60),
    (7, 0, 20, 'Product 3', 'prod-3', 3, 70),
    (8, 7, 20, 'Product 3A', 'prod-3-A', 3, 80),
    (9, 7, 20, 'Product 3B', 'prod-3-B', 3, 90),
    (10, 0, 50, 'Product 4', 'prod-4', 4, 100),
    (11, 10, 50, 'Product 4A', 'prod-4-A', 4, 100),
    (12, 10, 50, 'Product 4B', 'prod-4-B', 4, 100);
 

5.5 导入表数据

SPL接口不能直接访问 snowflake 自带数据库 SNOWFLAKE_SAMPLE_DATA.TPCH_SF1,但可将其中的表通过 CREATE TABLE … AS SELECT 等方式导入MYDB.PUBLIC.TABLE。
导入表 orders 的 sql 语句为:
CREATE TABLE MYDB.PUBLIC.ORDERS AS SELECT SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.ORDERS;
load data into Table方式导入: 也可将TPCH_SF1.ORDERS表数据导出成文件,通过文件 load data 方式导入表MYDB.PUBLIC.ORDERS

5.6 访问授权

将数据库 MYDB 及其下的数据表、文件等授权给应用 myAppSpl,使 SPL 函数接口能访问其下资源。
GRANT USAGE ON DATABASE mydb to APPLICATION myAppSpl;
GRANT USAGE ON SCHEMA mydb.public to APPLICATION myAppSpl;
GRANT READ,WRITE ON STAGE mydb.public.mystage to APPLICATION myAppSpl;
GRANT SELECT ON TABLE mydb.public.orders TO APPLICATION myAppSpl;
GRANT SELECT ON TABLE mydb.public.sample_product_data TO APPLICATION myAppSpl;
文件访问授权 stage, 数据表访问授权需要针对表名授权。
 

6. 函数说明

6.1 函数功能

消费用户安装 myAppSpl 可得到 SPL 提供了两个函数 runUDF、runSPL,可在 java, Sql WorkSheet 中使用。
A、runSPL 函数以存储过程方式调用,即 call runSPL() 方式调用,计算结果以 DataFrame 格式返回给函数调用端。
B、runUDF 函数是 UDF 接口,在 sql 语句用,用法如 select runUDF() from table。

6.2 函数参数

runUDF、runSPL都以 (spl, [array]) 格式接收 2 个参数 spl 和 array,参数 spl 指定编写好的脚本文件、计算表达式、sql 语句等,array 是 spl 中对应的参数,以数组方式传入,若无则可省略。

7. 调用函数

7.1 调用方法

写一个用Java程序调用接口runSPLrunUDF。其中runUDFSQL里用,通过java sql接口调用SQL语句;runSPL存储过程函数,通过java存储过程接口调用。调用时带上接口所在App位置以防出现找不到接口问题。
 
import java.util.HashMap;
import java.util.Map;
import com.snowflake.snowpark_java.Session;
 
public class InvokeTest {
private static final String PRIVATE_KEY_FILE = "D:/MySnowFlake/secret/rsa_key.p8";
       private Session m_session;
 
       public InvokeTest() {
              initDefaultSession()
       }
       // 连接信息设置
       private void initDefaultSession() {
              try {
                     Map<String, String> prop = new HashMap<>();
                     String url = "https://sqkhnfr-zilu.snowflakecomputing.com";
                     prop.put("WAREHOUSE", "SPLX_WH");
                     prop.put("DB", "MYDB");
                     prop.put("SCHEMA", "PUBLIC");
                     prop.put("USER", "un");
                     prop.put("URL", url);
                     prop.put("PRIVATE_KEY_FILE", PRIVATE_KEY_FILE);
                     prop.put("PRIVATE_KEY_FILE_PWD", "rootpwd");
                     prop.put("ROLE", "ACCOUNTADMIN");
                     prop.put("LEVEL", "WARNING");
                    
                     m_session = Session.builder().configs(prop).create();
              } catch (Exception e) {
                     e.printStackTrace();
              }
       }
       // 存储过程调用
       public void testStoredProcedure(String shell) {
              m_session.storedProcedure("myAppSpl.myschema.runSPL", shell).show();
       }
       // 在 SQL 里调用 UDFs
       public void testUdfs(String sql) {
              m_session.sql(sql).show();
       }
 
       public static void main(String[] args) {
              try {
                     InvokeTest cls = new InvokeTest();                  
                     String shell = "@mydb.public.mystage/vmTable.splx";
                     cls.testStoredProcedure(shell);
                      
                     String sql = "select myAppSpl.myschema.runUDF('=?', OBJECT_CONSTRUCT(*)) as jsons from public.sample_product_data";
                     cls.testUdfs(sql);                 
              } catch (Exception e) {
                     e.printStackTrace();
              }
       }
}
 
其中 PRIVATE_KEY_FILE 的公钥文件生成参考附录。

7.2 脚本用表数据计算

编写使用 orders 表中数据进行计算的脚本 queryOrder.splx 如下:

A B
1 =Squery("SELECT   O_ORDERDATE, O_ORDERSTATUS, O_TOTALPRICE FROM MYDB.PUBLIC.ORDERS where   O_ORDERKEY<3000000")
2 =A1.groups(year(O_ORDERDATE):year,O_ORDERSTATUS:status;sum(O_TOTALPRICE):amount)
3 return A2

脚本使用了 Squery(sql) 获取表数据, 将脚本放在 @mydb.public.mystage 下,在 Sql WorkSheet 中执行:
call myAppSpl.myschema.runSPL('@mydb.public.mystage/queryOrder.splx);
返回结果:

130png

7.3 脚本用组表数据计算

编写使用 score 组表数据进行计算的脚本 ctxScore.splx 如下:

A B
1 =Sfile("@MYDB.PUBLIC.MYSTAGE/score.ctx")
2 =A1.open()
3 =A2.cursor().fetch(100)
4 >A2.close()
5 return A3

脚本使用了 Sfile(@file) 读取文件获取数据, 将脚本放在 @mydb.public.mystage 下,在 Sql WorkSheet 执行:
call myAppSpl.myschema.runSPL('@mydb.public.mystage/ctxScore.splx);
返回结果:

131png

7.4 访问 S3 文件数据

将 S3 桶下文件导入 snowflake 的 mydb 库,
1 、生成文件格式
create or replace file format mys3csv
       type = 'CSV'
       field_delimiter = ','
       skip_header = 1;
2 、创建存储 MYS3STAGE
create or replace stage MYS3STAGE url='s3://un-bucket101/'
CREDENTIALS=(aws_key_id='xxxx' aws_secret_key='xxxxx')
file_format = mys3csv;
url 为 S3 的桶名,同时需要指定 aws_key_id 与 aws_secret_key;
创建成功后,可看到 s3://un-bucket101 下的文件同步到 MYS3STAGE:

132png


访问 MYS3STAGE 下的资源需要给 myAppSpl 授权:
GRANT READ,WRITE ON STAGE MYDB.PUBLIC.MYS3STAGE to APPLICATION myAppSpl;
调用接口访问:
call myAppSpl.MYSCHEMA.runSPL('=Sfile("@MYDB.PUBLIC.MYS3STAGE/testfile.csv").import@tc ()');
返回计算结果:

133png


snowflake 除了支持 aws s3 外,也支持 Microsoft azure、google gcs 存储,访问配置可参考 snowflake 官方文档。

7.5 函数 runUDF 使用

runUDF 是 UDFs 函数,以 sql 查询方式调用。
可结合 snowflake 自带函数 ARRAY_AGG(col…) 按列合并、ARRAY_CONSTRUCT(col…) 按行合并,在 sql 中调用参考脚本:
with temp_1 as
(
    SELECT 'John' AS my_col, 20 as age
    UNION ALL
    SELECT 'John' AS my_col, 21 as age
    UNION ALL
    SELECT 'John' AS my_col, 22 as age
    UNION ALL
    SELECT 'doe' AS my_col, 27 as age
    UNION ALL
    SELECT 'doe' AS my_col, 28 as age
     UNION ALL
    SELECT 'Tom' AS my_col, 30 as age
)
select a.my_col as names, runUDF('=?.(~.array().count())', ARRAY_AGG(ARRAY_CONSTRUCT(a.my_col)) ) as num
from temp_1 a group by names;
返回结果:

134png


array 传递的数据是一维数组转换成序列,二维数组转换成序表。
 

附 录

附录 A:注册 snowflake 帐号

用户需要用企业邮件注册 snowflake,个人邮件注册不支持。这里以选择云服务商 aws 为例说明,测试时要用到 S3 存储。

A.1 注册入口

注册网址:www.snowflake.com, 点击” START FOR FREE”开始注册。

140png

A.2 填写注册信息

141png

A.3 选择云服务商

选择 aws 云及 region 为 US West。

说明:对于中国用户,有的需要翻墙代理才能注册,否则可能会卡在这里不动。

142png

A.4 设置密码

当注册完后预留的邮箱会收到确认网址,打开网址,输入注册时的帐号, 设置密码, 按指导说明操作即可,完成后登陆进入 snowflake 操作界面。

附录 B:登录检验设置

用 snowflake 提供的工具 snowsql、客户端远程连接、jdbc 连接时,都需要登陆验证检测。如果只在 snowsight Sql WorkSheet 下使用,此步可跳过。参考文档:
https://docs.snowflake.com/en/user-guide/key-pair-auth

https://streamsets.com/blog/snowflake-key-pair-authentication/

B.1 生成公钥、私钥

openssl工具生成私钥、公钥文件。(后面 snowsql、java 测试用)
A、生成私钥:
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
输入 passwd: rootpwd,生成文件 rsa_key.p8。

B、生成公钥:
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
生成文件 rsa_key.pub。

B.2 设置公钥

将公钥与帐号绑定,在 snowsight 中操作,用户名为登陆帐号,RSA_PUBLIC_KEY 值为文件 rsa_key.pub 的内容。

143png

附录 C:使用 snowsql 工具

snowsql 用于对 snowflake 数据库的管理、上传下载文件等。
安装 snowsql,
参考文档:https://docs.snowflake.com/en/user-guide/snowsql-install-config,
https://docs.snowflake.com/en/user-guide/admin-account-identifier
下载安装即可使用。

控制台下登陆:

snowsql.exe -o log_level=DEBUG -a UUTXYFY-RWB64272 -u pamire120 --private-key-path D:\dev\workspace\snowflake\MySnowFlake\secret\rsa_key.p8a

-a 参数是 Account identifiers,

144png

登陆时需要输入生成公钥时的密码串 rootpwd。

附录 D:创建 Warehouse

用户若还没有一个自己的 warehouse,则需要新建一个 warehouse, 以指定其运行的 VM 环境。在 Admin->Warehouse 下新建名为 SPL_DEMO 的 warehouse。

145png

附录 E:跟踪日志

在 Snowflake 平台上执行脚本或 sql 语句查询,若执行有问题,日志管理 Monitoring
->Query History 中没有 java 程序中的输出日志, 且没有异常的具体信息。snowflake 提供了日志事件机制, 将程序输出日志存储到用户自定义的事件表,有问题时可查询跟踪。

E.1 创建事件表

新建数据库,创建事件表 myevents,并与当前帐号关联。
CREATE OR REPLACE DATABASE spl_log_trace_db;
CREATE OR REPLACE EVENT TABLE myevents;
ALTER ACCOUNT SET EVENT_TABLE = spl_log_trace_db.public.myevents;
ALTER SESSION SET LOG_LEVEL = INFO;

E.2 查看日志


调用 SPL接口 后,通过 sql 语句查看日志:
SELECT
  TIMESTAMP AS time,
  RESOURCE_ATTRIBUTES['snow.executable.name'] as executable,
  RECORD['severity_text'] AS severity,
  VALUE AS message
FROM
  spl_log_trace_db.public.myevents
WHERE
  RECORD_TYPE = 'LOG' ;

146png
可看到程序输出日志与错误原因细节。

E.3 删除日志

跟踪时,日志太多或调用 SPL 接口前可删除日志,以方便找到所需要的日志。
delete from spl_log_trace_db.public.myevents;

附录 F:创建 consumer 帐号:

试用帐号生成 App 安装包时需要指定 consumer 帐号。同时,另一用户在消费端下安装 App 使用 SPL 接口,也需要用 consumer 帐号。

在菜单栏 Admin->Accounts 中创建消费帐号。

147png


填写 consumer 帐号信息:

148png
consumer 帐号创建成功返回如下:

149png


附件:splShellzip