【问题标题】:Unable to connect Snowflake through AWS lambda using JAVA 8无法使用 JAVA 8 通过 AWS lambda 连接雪花
【发布时间】:2020-05-20 12:25:15
【问题描述】:

尝试使用 Java 8 从 AWS lambda 连接 Snowflake。

  Class.forName("net.snowflake.client.jdbc.SnowflakeDriver"); // v3.9.1 as maven dependency

            final Properties snowflakProperties = new Properties();
            snowflakProperties.put("user", "username");
            snowflakProperties.put("password", "password");
            snowflakProperties.put("account", "account"); // accountname.regionname
            snowflakProperties.put("db", "dbname");
            snowflakProperties.put("schema", "schemaname");
            snowflakProperties.put("role", "rolename");

            DriverManager.getConnection("jdbc:snowflake://accountname.snowflakecomputing.com", 
                                                       snowflakProperties);

很遗憾,无法连接,并且 lambda 超时。 已经进行了以下试验来解决:

  1. 在 AWS lambda 中设置环境变量,例如 SF_TEMPORARY_CREDENTIAL_CACHE_DIRSF_OCSP_RESPONSE_CACHE_DIR/tmp/。还尝试将 JAVA_TOOL_OPTIONS 作为 -Duser.home=/tmp/

  2. 已尝试 JDBC 版本:3.11.1、3.9.1、3.8.4

  3. 试图将缓存目录设置为 /home/,这会引发异常并显示消息 Failed to touch the cache file: /home/ocsp_response_cache.json

仍然没有得到适当的解决方案。 AWS lambda 是否不允许使用临时目录获取雪花连接?

因此,期待尽快解决

谢谢。

【问题讨论】:

  • 这是一个棘手的问题,因为您似乎已经尝试了我所见过的通常可以解决问题的所有方法。除了这里提到的环境变量之外,也许您还可以尝试设置 JVM 选项?我还将确保您从一台新机器开始仅用于测试,这样您就没有任何冲突的依赖项或 JDBC 驱动程序版本。最新的 JDBC 驱动程序应该不太可能出现异常。 docs.snowflake.com/en/user-guide/…
  • 感谢@Suzy Lockwood 的观察,尝试并获得了与第 1 点和第 3 点中提到的相同的结果
  • 奇怪的是,设置这些变量似乎不起作用。我看到了一个相关的 GitHub 问题,看起来它已在 3.11.0 中得到解决。也许尝试那个确切的版本以确保它不是 3.11.1 中的一些奇怪的回归。 github.com/snowflakedb/snowflake-jdbc/issues/115 查找可写目录的 JDBC 代码(默认根据需要在 tmp 中创建文件)在这里:github.com/snowflakedb/snowflake-jdbc/blob/master/src/main/java/…
  • 您在 Lambda 中设置这些环境变量,对吗,而不是操作系统?是否可以执行任何 JDBC 或 Lambda 日志记录来确保它们被拾取? docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html
  • 我唯一的另一个想法是尝试使用 Python。我知道你想使用 JAVA,但也许在 Python 中设置它会提供一些线索。

标签: java amazon-web-services jdbc aws-lambda snowflake-cloud-data-platform


【解决方案1】:
I tested the Lambda fn with java .Change the values accordingly.
You can try this one below:

-----------------------------------------------------------------------------

package com.snowflake.LambdaTest;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class LambdaRequestHandler implements RequestHandler<Object, String> {
    public String handleRequest(Object input, Context context) {
        String data= input != null ? input.toString() : "{}";
        context.getLogger().log("Input: \n" + data);
        context.getLogger().log("Connecting to Snowflake DB ......\n");

        String connectionUrl = "jdbc:snowflake://<URL>/?account=<AccountName>&warehouse=<WareHouseName>&role=<RoleName>&db=<DBName>&schema=<SchemaName>&tracing=ALL";

        String user = "<UserName>";
        String passwd = "<Password>";

        Properties _connectionProperties = new Properties();
        _connectionProperties.put("user", user);
        _connectionProperties.put("password", passwd);

        try {
            Class.forName("net.snowflake.client.jdbc.SnowflakeDriver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        context.getLogger().log("Getting Conn...\n");
        Connection testConnection = null;

        try {
            testConnection = DriverManager.getConnection(connectionUrl, _connectionProperties);

            testConnection.setAutoCommit(false);
            Statement stat = testConnection.createStatement();
            ResultSet rs = stat.executeQuery("select * from <TableName>");
            while (rs.next()) {
                System.out.println(rs.getString(1));
            }

        } catch (SQLException e) {

            e.printStackTrace();
        }
        try {
            testConnection.close();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return "Success";

    }

}
----------------------------------------------------------------------

【讨论】:

  • 感谢您的解决方案。它适用于系统的一般项目,但不适用于 AWS lambda 函数。
  • 你可以试试这个功能,这样的话。
  • 当 lambda 在 VPC 中时出现问题。一旦我们解耦 VPC,它就会建立连接。除此之外,JDBC 连接 URL 必须同时具有帐户名和区域,但声明的参数(在我的例子中是 snowflakProperties)只需要帐户名。如果区域通过则抛出无效的用户名/密码错误。感谢您的帮助
猜你喜欢
  • 2022-11-14
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 2020-08-31
  • 2020-12-31
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
相关资源
最近更新 更多