我正在尝试使用来自.NEt Core 2.0 C#App的AWS Lambda连接到RedShift数据库。
以下是我的方法。
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(无法打开连接)。
我收到了Bellow Error。
需要具有最低版本2.3.1的依赖性unixODBC。 无法加载DLL'libodbc.so.2':指定的模块或其中一个 无法找到依赖项。
看来有些odbc问题,如何解决?
答案 0 :(得分:0)
在非Windows平台上使用System.Data.Odbc时,必须安装unixODBC(版本2.3.1或更高版本)。然后,您需要安装所需的ODBC驱动程序(在您的情况下,这是Amazon Redshift ODBC驱动程序)并将其注册在odbcinst.ini中。如果是AWS Lambda,则需要检查如何通过部署包来部署unixODBC和Redshift ODBC驱动程序。
答案 1 :(得分:0)
我还尝试使用ODBC从lambda函数的redshift中获取数据,但出现问题“需要最低版本2.3.1的依赖项unixODBC”。
如本线程注释中所述,使用 Npgsql.EntityFrameworkCore.PostgreSQL 库代替使用ODBC。我正在尝试将其组合在一起以提供帮助。这是我的代码,该代码从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;
}