C# AWS Lambda使用ODBC连接连接到Redshift DB
我正在尝试使用.NETCore2.0c#App中的AWS Lambda连接到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
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
我找到了解决这个问题的方法。嗨,维塔利,我也面临这个问题。你能帮我更详细地了解一下吗