Snowflake 驱动程序¶
适用于: C/C++, GLib/Ruby, Go, Python, R
Snowflake 驱动程序提供对 Snowflake 数据仓库的访问。
安装¶
对于 conda-forge 用户
mamba install libadbc-driver-snowflake
go get github.com/apache/arrow-adbc/go/adbc/driver/snowflake
# For conda-forge
mamba install adbc-driver-snowflake
# For pip
pip install adbc_driver_snowflake
# install.packages("pak")
pak::pak("apache/arrow-adbc/r/adbcsnowflake")
用法¶
要连接到 Snowflake 数据库,您可以在构造 AdbcDatabase
时提供 "uri" 参数。
#include "arrow-adbc/adbc.h"
// Ignoring error handling
struct AdbcDatabase database;
AdbcDatabaseNew(&database, nullptr);
AdbcDatabaseSetOption(&database, "driver", "adbc_driver_snowflake", nullptr);
AdbcDatabaseSetOption(&database, "uri", "<snowflake uri>", nullptr);
AdbcDatabaseInit(&database, nullptr);
import adbc_driver_snowflake.dbapi
with adbc_driver_snowflake.dbapi.connect("<snowflake uri>") as conn:
pass
library(adbcdrivermanager)
# Use the driver manager to connect to a database
uri <- Sys.getenv("ADBC_SNOWFLAKE_TEST_URI")
db <- adbc_database_init(adbcsnowflake::adbcsnowflake(), uri = uri)
con <- adbc_connection_init(db)
import (
"context"
"github.com/apache/arrow-adbc/go/adbc"
"github.com/apache/arrow-adbc/go/adbc/driver/snowflake"
)
func main() {
var drv snowflake.Driver
db, err := drv.NewDatabase(map[string]string{
adbc.OptionKeyURI: "<snowflake uri>",
})
if err != nil {
// handle error
}
defer db.Close()
cnxn, err := db.Open(context.Background())
if err != nil {
// handle error
}
defer cnxn.Close()
}
URI 格式¶
Snowflake URI 应采用以下格式之一
user[:password]@account/database/schema[?param1=value1¶mN=valueN]
user[:password]@account/database[?param1=value1¶mN=valueN]
user[:password]@host:port/database/schema?account=user_account[¶m1=value1¶mN=valueN]
host:port/database/schema?account=user_account[¶m1=value1¶mN=valueN]
或者,可以完全使用其他可用选项或 URI 和其他选项的某种组合来提供配置,而不是提供完整的 URI。 如果提供了 URI,将首先对其进行解析,并且任何显式提供的选项都将覆盖从 URI 解析的任何内容。
支持的功能¶
Snowflake 驱动程序通常支持 ADBC API 规范 1.0.0 中定义的功能,以及一些额外的自定义选项。
身份验证¶
Snowflake 要求启用某种形式的身份验证。 默认情况下,它将尝试使用用户名/密码身份验证。 用户名和密码可以在 URI 中提供,也可以通过 AdbcDatabase
的 username
和 password
选项提供。
或者,可以指定和自定义其他类型的身份验证。 有关所有选项的详细信息,请参见下面的“客户端选项”。
SSO 身份验证¶
Snowflake 支持 单点登录。 如果您的帐户已配置了 SSO,则可以通过在构造 AdbcDatabase
时设置以下选项来将其与 Snowflake 驱动程序一起使用
adbc.snowflake.sql.account
:您的 Snowflake 帐户。 (例如,如果您登录到https://foobar.snowflakecomputing.com
,则您的帐户标识符为foobar
。)adbc.snowflake.sql.auth_type
:auth_ext_browser
。username
:您的用户名。 (这可能是您的电子邮件,例如jdoe@example.com
。)
应该会出现一个新的浏览器选项卡或窗口,您可以在其中继续登录。 完成此操作后,您将拥有一个完整的 ADBC 数据库/连接对象。 一些用户报告需要其他配置选项,例如 adbc.snowflake.sql.region
和 adbc.snowflake.sql.uri.*
(请参见下面的列表)。
import adbc_driver_snowflake.dbapi
# This will open a new browser tab, and block until you log in.
adbc_driver_snowflake.dbapi.connect(db_kwargs={
"adbc.snowflake.sql.account": "foobar",
"adbc.snowflake.sql.auth_type": "auth_ext_browser",
"username": "jdoe@example.com",
})
library(adbcdrivermanager)
db <- adbc_database_init(
adbcsnowflake::adbcsnowflake(),
adbc.snowflake.sql.account = 'foobar',
adbc.snowflake.sql.auth_type = 'auth_ext_browser'
username = 'jdoe@example.com',
)
# This will open a new browser tab, and block until you log in.
con <- adbc_connection_init(db)
import (
"context"
"github.com/apache/arrow-adbc/go/adbc"
"github.com/apache/arrow-adbc/go/adbc/driver/snowflake"
)
func main() {
var drv snowflake.Driver
db, err := drv.NewDatabase(map[string]string{
snowflake.OptionAccount: "foobar",
snowflake.OptionAuthType: snowflake.OptionValueAuthExternalBrowser,
adbc.OptionKeyUsername: "jdoe@example.com",
})
if err != nil {
// handle error
}
defer db.Close()
cnxn, err := db.Open(context.Background())
if err != nil {
// handle error
}
defer cnxn.Close()
}
批量摄取¶
支持批量摄取。 下面提供了从 Arrow 类型到 Snowflake 类型的映射。
批量摄取通过将 Arrow 数据写入 Parquet 文件并将 (通过 PUT) 上传到临时内部阶段来实现。 执行一个或多个 COPY 查询,以便将数据加载到目标表中。
为了使驱动程序利用此临时阶段,用户必须具有架构上的 CREATE STAGE <https://docs.snowflake.com/en/sql-reference/sql/create-stage> 权限。 此外,必须设置会话的当前数据库和架构。 如果未设置,驱动程序执行的 CREATE TEMPORARY STAGE
命令可能会失败,并显示以下错误
CREATE TEMPORARY STAGE ADBC$BIND FILE_FORMAT = (TYPE = PARQUET USE_LOGICAL_TYPE = TRUE BINARY_AS_TEXT = FALSE)
CANNOT perform CREATE STAGE. This session does not have a current schema. Call 'USE SCHEMA' or use a qualified name.
以下非正式基准测试演示了使用默认摄取设置的预期性能
Running on GCP e2-standard-4 (4 vCPU, 16GB RAM)
Snowflake warehouse size M, same GCP region as Snowflake account
Default ingestion settings
TPC-H Lineitem (16 Columns):
Scale Factor 1 (6M Rows): 9.5s
Scale Factor 10 (60M Rows): 45s
摄取的默认设置对于许多实际配置应该非常平衡。 如果需要,可以使用 AdbcStatement
对象上的以下选项来调整性能和资源使用情况
adbc.snowflake.statement.ingest_writer_concurrency
并行写入 Parquet 文件的数量。 默认情况下,会尝试基于检测到的逻辑核心最大化 worker,但如果在受限环境中运行,则可能需要调整。 如果设置为 0,则使用默认值。 不能为负数。
adbc.snowflake.statement.ingest_upload_concurrency
并行上传 Parquet 文件的数量。 更高的并发性可以平滑 TCP 拥塞并有助于利用可用的网络带宽,但会增加内存利用率。 默认为 8。 如果设置为 0,则使用默认值。 不能为负数。
adbc.snowflake.statement.ingest_copy_concurrency
并发运行的最大 COPY 操作数。 通过在文件仍在上传时执行 COPY 查询来优化批量摄取性能。 Snowflake COPY 速度随仓库大小而变化,因此较小的仓库可能会受益于将此值设置得更高,以确保长时间运行的 COPY 查询不会阻止加载新上传的文件。 默认为 4。 如果设置为 0,则仅在所有文件上传完成后,才会在摄取过程中执行单个 COPY 查询。 不能为负数。
adbc.snowflake.statement.ingest_target_file_size
摄取期间写入的 Parquet 文件的近似大小。 实际大小会略大,具体取决于页脚/元数据的大小。 默认为 10 MB。 如果设置为 0,则文件大小没有限制。 不能为负数。
分区结果集¶
当前不支持分区结果集。
性能¶
查询 Snowflake 数据时,结果可能会从多个端点并行获取。 每个端点都排队了有限数量的批次,但数据始终按照端点的顺序返回给客户端。
为了管理结果获取的性能,有两个选项可以控制缓冲和并发行为。 这些选项只能在 AdbcStatement
对象上设置
adbc.rpc.result_queue_size
记录读取器中要排队的批次数量。 默认为 200。 必须是大于 0 的整数。
adbc.snowflake.rpc.prefetch_concurrency
一次从 snowflake 获取的并发流的数量。 默认为 10。 必须是大于 0 的整数。
事务¶
支持事务。 请记住,如果运行任何 DDL 语句(例如 CREATE TABLE
),Snowflake 事务将隐式提交。
客户端选项¶
用于创建 Snowflake 数据库连接的选项可以自定义。 这些选项与 Snowflake Config 对象 <https://pkg.go.dev/github.com/snowflakedb/gosnowflake#Config> 映射 1:1。
adbc.snowflake.sql.db
此会话应默认使用的数据库。
adbc.snowflake.sql.schema
此会话应默认使用的架构。
adbc.snowflake.sql.warehouse
此会话应默认使用的仓库。
adbc.snowflake.sql.role
应用于身份验证的角色。
adbc.snowflake.sql.region
用于构造连接 URI 的 Snowflake 区域。
adbc.snowflake.sql.account
应用于身份验证和构建连接 URI 的 Snowflake 帐户。
adbc.snowflake.sql.uri.protocol
这应该是 http 或 https。
adbc.snowflake.sql.uri.port
用于构造连接 URI 的端口。
adbc.snowflake.sql.uri.host
用于构造要连接到的 URL 的显式主机。
adbc.snowflake.sql.auth_type
允许指定替代类型的身份验证,允许的值为
auth_snowflake
:常规用户名/密码身份验证(这是默认设置)auth_oauth
:使用 OAuth 身份验证进行 snowflake 连接。auth_ext_browser
:使用外部浏览器访问 FED 并执行 SSO 身份验证。auth_okta
:使用原生 Okta URL 使用 Okta 执行 SSO 身份验证auth_jwt
:使用提供的 JWT 执行身份验证。auth_mfa
: 使用用户名和密码进行多因素身份验证 (MFA)。
adbc.snowflake.sql.client_option.auth_token
如果使用 OAuth 或其他形式的身份验证,此选项允许您显式指定用于连接的令牌。
adbc.snowflake.sql.client_option.okta_url
如果使用
auth_okta
,则需要此选项才能指定用于 SSO 身份验证的 Okta URL。adbc.snowflake.sql.client_option.login_timeout
指定登录重试超时时间,不包括网络往返和读取 http 响应的时间。该值应按照 此处 <https://pkg.go.dev/time#ParseDuration> 的描述进行格式化,例如
300ms
、1.5s
或1m30s
。即使接受负值,也将使用此类持续时间的绝对值。adbc.snowflake.sql.client_option.request_timeout
指定请求重试超时时间,不包括网络往返和读取 http 响应的时间。该值应按照 此处 <https://pkg.go.dev/time#ParseDuration> 的描述进行格式化,例如
300ms
、1.5s
或1m30s
。即使接受负值,也将使用此类持续时间的绝对值。adbc.snowflake.sql.client_option.jwt_expire_timeout
JWT 过期将在此超时后发生。该值应按照 此处 <https://pkg.go.dev/time#ParseDuration> 的描述进行格式化,例如
300ms
、1.5s
或1m30s
。即使接受负值,也将使用此类持续时间的绝对值。adbc.snowflake.sql.client_option.client_timeout
指定网络往返和读取 http 响应的超时时间。该值应按照 此处 <https://pkg.go.dev/time#ParseDuration> 的描述进行格式化,例如
300ms
、1.5s
或1m30s
。即使接受负值,也将使用此类持续时间的绝对值。adbc.snowflake.sql.client_option.app_name
允许为连接指定 Snowflake 的应用程序名称。
adbc.snowflake.sql.client_option.tls_skip_verify
禁用服务器 TLS 证书的验证。值应为
true
或false
。adbc.snowflake.sql.client_option.ocsp_fail_open_mode
控制 OCSP 的故障开放模式。默认值为
true
。值应为true
或false
。adbc.snowflake.sql.client_option.keep_session_alive
即使在连接关闭后,也允许会话保持活动状态。值应为
true
或false
。adbc.snowflake.sql.client_option.jwt_private_key
指定用于签署 JWT 以进行身份验证的 RSA 私钥。这应该是包含要读取和解析的 PKCS1 私钥的文件路径。通常以 “RSA PRIVATE KEY” 类型的 PEM 块编码。
adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_value
解析加密或未加密的 PKCS #8 私钥,而无需从文件系统中读取它。如果使用加密,则需要
adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_password
值,并用于解密。adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_password
传递加密的 PKCS #8 值时使用的密码。
adbc.snowflake.sql.client_option.disable_telemetry
Snowflake 驱动程序允许遥测信息,可以通过将其设置为
true
来禁用它。值应为true
或false
。adbc.snowflake.sql.client_option.config_file
指定客户端配置 JSON 文件的位置。 有关更多详细信息,请参见 [Snowflake Go 文档](https://github.com/snowflakedb/gosnowflake/blob/a26ac8a1b9a0dda854ac5db9c2c145f79d5ac4c0/doc.go#L130)。
adbc.snowflake.sql.client_option.tracing
设置日志记录级别
adbc.snowflake.sql.client_option.cache_mfa_token
当
true
时,MFA 令牌将缓存在凭据管理器中。 在 Windows/OSX 上默认为true
,在 Linux 上默认为false
。adbc.snowflake.sql.client_option.store_temp_creds
当
true
时,ID 令牌将缓存在凭据管理器中。 在 Windows/OSX 上默认为true
,在 Linux 上默认为false
。adbc.snowflake.sql.client_option.use_high_precision
当
true
时,类型为NUMBER
的定点 Snowflake 列将使用NUMBER
类型的精度和小数位数作为Decimal128
类型的 Arrow 列返回。 当false
时,小数位数为 0 的NUMBER
列将作为Int64
类型的 Arrow 列返回,而小数位数不为零的列将作为Float64
类型的 Arrow 列返回。 默认值为true
。
元数据¶
调用 AdbcConnectionGetTableSchema()
时,返回的 Arrow Schema 将包含每个字段的元数据
DATA_TYPE
这将是一个字符串,其中包含此列的原始 Snowflake 数据类型
PRIMARY_KEY
这将是
Y
或N
之一,以指示列是否为主键。
此外,来自查询的结果流的 schema 将在每个字段上包含以下元数据键
logicalType
此列的 Snowflake 逻辑类型。 将是
fixed
、real
、text
、date
、variant
、timestamp_ltz
、timestamp_ntz
、timestamp_tz
、object
、array
、binary
、time
、boolean
之一。precision
表示字段的 Snowflake 精度的一个整数。
scale
表示此字段中值的 Snowflake 小数位数的一个整数。
charLength
如果是文本字段,则这将等效于
VARCHAR(#)
参数#
。byteLength
无论 Arrow 中字段的类型如何,都将包含从 Snowflake 返回的原始数据的长度(以字节为单位)。
类型支持¶
由于 Snowflake 类型不一定与 Arrow 类型一一对应,因此以下是请求数据时应该期望的内容。 进行任何指示的转换是为了确保记录批处理流的一致性。
Snowflake 类型 |
Arrow 类型 |
注释 |
---|---|---|
整数类型 |
number(38, 0) |
Snowflake 中的所有整数类型都存储为数字,不能指定精度或小数位数。 |
float/double |
float64 |
Snowflake 不区分 float 或 double。 两者都是 64 位值。 |
decimal/numeric |
numeric |
Snowflake 将遵守 Arrow 类型的精度/小数位数。 有关此行为的例外情况,请参见 |
time |
time64[ns] |
对于提取,也可以使用 time32。 |
date |
date32 |
对于提取,也可以使用 date64。 |
timestamp_ltz
timestamp_ntz
timestamp_tz
|
timestamp[ns] |
将使用本地时区,timestamp_ntz 除外,它不是一个瞬间。 在这种情况下,该类型中将不存在时区。 物理值将被 UTC 标准化。 |
variant
object
array
|
string |
Snowflake 不提供有关嵌套类型的信息。 这些值将是以类似于 JSON 的格式的字符串,可以对其进行解析。 Arrow 类型将包含一个元数据键 |
geography
geometry
|
string |
这些类型当前没有规范的 Arrow(扩展)类型,因此它们将作为 Snowflake 提供的字符串值返回。 |