C# AWS Lambda使用ODBC连接连接到Redshift DB

C# AWS Lambda使用ODBC连接连接到Redshift DB,c#,lambda,odbc,aws-lambda,amazon-redshift,C#,Lambda,Odbc,Aws Lambda,Amazon Redshift,我正在尝试使用.NETCore2.0c#App中的AWS Lambda连接到RedShift DB 下面是我的方法 string connString = "Driver={Amazon Redshift (x86)};" + String.Format("Server={0};Database={1};" + "UID={2};PWD={3};Port={4};SSL=true;Sslmode=Require", RedS

我正在尝试使用.NETCore2.0c#App中的AWS Lambda连接到RedShift DB

下面是我的方法

string connString = "Driver={Amazon Redshift (x86)};" +
            String.Format("Server={0};Database={1};" +
            "UID={2};PWD={3};Port={4};SSL=true;Sslmode=Require",
            RedShiftServer, RedShiftDBName, RedShiftUsername,RedShiftPassword, RedShiftPort);
OdbcConnection conn = new OdbcConnection(connString);
conn.Open();
但在部署到Lambda函数后,我无法连接到RedShift DB(无法打开连接)

我犯了一个错误

“需要最低版本为2.3.1的依赖项unixODBC。 无法加载DLL“libodbc.so.2”:指定的模块或其 找不到依赖项


似乎有些odbc问题,如何解决?

在非Windows平台上使用System.Data.odbc时,必须安装unixODBC(2.3.1版或更高版本)。然后,需要安装所需的odbc驱动程序(在您的情况下,这是Amazon Redshift odbc驱动程序)并在odbcinst.ini中注册。如果是AWS Lambda,您需要检查如何在部署包中部署unixODBC和Redshift ODBC驱动程序。

我也尝试使用ODBC从Redshift获取Lambda函数的数据,但遇到了“需要最低版本为2.3.1的依赖unixODBC”的问题

不要使用ODBC,而是使用本线程注释中提到的Npgsql.EntityFrameworkCore.PostgreSQL库。我正试图将其组合起来以提供帮助。下面是我的代码,它从redshift中读取ODBC的连接字符串,并将其与模型绑定,redshift中表的类型和列名应该相同套管的厚度

 public IEnumerable<T> ExcecuteSelectCommand<T>(string command, string connectionString)
    {
        var relevantConnectionString = GetConnectionStringWithoutDriver(connectionString);
        using (var conn = new NpgsqlConnection(relevantConnectionString))
        {
            try
            {
                conn.Open();
                using (var cmd = new NpgsqlCommand())
                {
                    cmd.Connection = conn;
                    cmd.CommandText = command;
                    var reader = cmd.ExecuteReader();
                    return CreateList<T>(reader);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("There was exception while excecuting the Select Command for Detail, here is exception detail. " + ex.Message, ex);
            }
        }
    }

    private string GetConnectionStringWithoutDriver(string connection)
    {
        return connection.Replace("Driver={Amazon Redshift (x64)}; ", string.Empty);
    }


    private List<T> CreateList<T>(NpgsqlDataReader reader)
    {
        var results = new List<T>();
        Func<NpgsqlDataReader, T> readRow = this.GetReader<T>(reader);

        while (reader.Read())
        {
            try
            {
                var readData = readRow(reader);
                results.Add(readData);

            }
            catch
            {
                throw new Exception("Data mismatch exception has occured");
                //Log the information when data failed to load
            }

        }

        return results;
    }

    private Func<NpgsqlDataReader, T> GetReader<T>(NpgsqlDataReader reader)
    {
        Delegate resDelegate;

        List<string> readerColumns = new List<string>();
        for (int index = 0; index < reader.FieldCount; index++)
        {
            readerColumns.Add(reader.GetName(index));
        }

        // determine the information about the reader
        var readerParam = Expression.Parameter(typeof(NpgsqlDataReader), "reader");
        var readerGetValue = typeof(NpgsqlDataReader).GetMethod("GetValue");

        // create a Constant expression of DBNull.Value to compare values to in reader
        var dbNullValue = typeof(System.DBNull).GetField("Value");
        //var dbNullExp = Expression.Field(Expression.Parameter(typeof(System.DBNull), "System.DBNull"), dbNullValue);
        var dbNullExp = Expression.Field(expression: null, type: typeof(DBNull), fieldName: "Value");
        // loop through the properties and create MemberBinding expressions for each property
        List<MemberBinding> memberBindings = new List<MemberBinding>();
        foreach (var prop in typeof(T).GetProperties())
        {
            // determine the default value of the property
            object defaultValue = null;
            if (prop.PropertyType.IsValueType)
                defaultValue = Activator.CreateInstance(prop.PropertyType);
            else if (prop.PropertyType.Name.ToLower().Equals("string"))
                defaultValue = string.Empty;

            if (readerColumns.Contains(prop.Name.ToLower()))
            {
                // build the Call expression to retrieve the data value from the reader
                var indexExpression = Expression.Constant(reader.GetOrdinal(prop.Name.ToLower()));
                var getValueExp = Expression.Call(readerParam, readerGetValue, new Expression[] { indexExpression });

                // create the conditional expression to make sure the reader value != DBNull.Value
                var testExp = Expression.NotEqual(dbNullExp, getValueExp);
                var ifTrue = Expression.Convert(getValueExp, prop.PropertyType);
                var ifFalse = Expression.Convert(Expression.Constant(defaultValue), prop.PropertyType);

                // create the actual Bind expression to bind the value from the reader to the property value
                MemberInfo mi = typeof(T).GetMember(prop.Name)[0];
                MemberBinding mb = Expression.Bind(mi, Expression.Condition(testExp, ifTrue, ifFalse));
                memberBindings.Add(mb);
            }
        }

        // create a MemberInit expression for the item with the member bindings
        var newItem = Expression.New(typeof(T));
        var memberInit = Expression.MemberInit(newItem, memberBindings);


        var lambda = Expression.Lambda<Func<NpgsqlDataReader, T>>(memberInit, new ParameterExpression[] { readerParam });
        resDelegate = lambda.Compile();

        return (Func<NpgsqlDataReader, T>)resDelegate;
    }
public IEnumerable ExcecuteSelectCommand(字符串命令,字符串连接字符串)
{
var relevantConnectionString=getconnectionstringwhithoutdriver(connectionString);
使用(var conn=新的NpgsqlConnection(relevantConnectionString))
{
尝试
{
conn.Open();
使用(var cmd=new NpgsqlCommand())
{
cmd.Connection=conn;
cmd.CommandText=命令;
var reader=cmd.ExecuteReader();
返回CreateList(读卡器);
}
}
捕获(例外情况除外)
{
抛出新异常(“执行Select命令获取详细信息时出现异常,这里是异常详细信息。”+ex.Message,ex);
}
}
}
私有字符串GetConnectionString不带驱动程序(字符串连接)
{
returnconnection.Replace(“Driver={amazonredshift(x64)};”,string.Empty);
}
私有列表CreateList(NpgsqlDataReader)
{
var results=新列表();
Func readRow=this.GetReader(reader);
while(reader.Read())
{
尝试
{
var readData=readRow(读卡器);
结果。添加(读取数据);
}
抓住
{
抛出新异常(“发生数据不匹配异常”);
//加载数据失败时记录信息
}
}
返回结果;
}
私有Func GetReader(NpgsqlDataReader)
{
代表再代表;
List readerColumns=新列表();
for(int index=0;index
我找到了解决这个问题的方法。嗨,维塔利,我也面临这个问题。你能帮我更详细地了解一下吗