Apache Beam提供了JDBCIO连接器以连接到CloudSql postgreSQL。我的工作从pub / sub中读取一个事件。事件正文如下:
tableName,
list<value>
我需要根据从消息中获得的表名写入表。
JDBCIO已经准备好了一条语句,该语句使我可以在插入查询中参数化值。但是我需要根据事件中存在的信息动态生成插入查询。
pipeline
.apply(PubsubIO.readStrings().fromSubscription())
.apply(convertToKV())
.apply(JdbcIO.<List<String>>>write()
.withDataSourceConfiguration(JdbcIO.DataSourceConfiguration.create(
"com.mysql.jdbc.Driver", "jdbc:mysql://hostname:3306/mydb")
.withUsername("username")
.withPassword("password"))
.withStatement("insert into Person values(?, ?)")
.withPreparedStatementSetter(new JdbcIO.PreparedStatementSetter<KV<Integer, String>>() {
public void setParameters(KV<Integer, String> element, PreparedStatement query)
throws SQLException {
i=0
for each element in list
query.setInt(i, element.get(i);
i++;
}
})
);
我应该能够基于来自pcollection的输入事件动态创建SQL语句。 我的select语句应基于列表值和表名动态生成。请让我知道我们是否可以这样做。
更新:-
im试图在parDo函数中手动调用jdbc驱动程序,但出现以下错误。 找不到适用于jdbcURL的驱动程序。
请让我知道我是否缺少任何内容:
@Setup
public void doAnyRequiredSetup() throws SQLException
{
LoggingContextUtil.installContext(loggingContext);
connection=DriverManager.getConnection(JdbcUrl,user,password);
statement=connection.createStatement();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("In doAnyRequiredSetup logging Context is now set and JDBC connection is .");
}
}
@SuppressWarnings("unchecked")
@ProcessElement
public void processElement(ProcessContext context)
{
JsonNode element=context.element();
try {
String query=formatQuery(baseQuery);
boolean result=statement.execute(query);
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("Executed query : "+query+" and the result is "+ result);
}
} catch (IllegalArgumentException | SQLException e) {
ErrorMessage em = new ErrorMessage(element.toString(), "Insert Query Failed", e.getMessage());
context.output(ValidateTagHelper.FAILURE_TAG,em);
}
}
答案 0 :(得分:0)
基于输入元素,不能在JdbcIO上进行动态查询。 必须根据需要重置ParDo,您可以重写ParDo,以手动调用JDBC驱动程序。
如果找到其他解决方法,则可以将输入PColleciton分为多个输出。如果您的用例仅限于您可以根据输入从中选择的一组预定义查询,那么这将起作用。这样,您可以将输入分成多个PCollection,然后将不同配置的IO附加到每个PCollection。
https://cloud.google.com/blog/products/gcp/guide-to-common-cloud-dataflow-use-case-patterns-part-1
答案 1 :(得分:0)
您可以尝试读取具有属性的pubsub消息,并且可以在属性中以键值对的形式传递表名和值。
DECLARE @ID int = 1;
WITH VTE AS(
SELECT *
FROM (VALUES(1,3),
(2,1),
(3,11),
(4,2),
(5,4),
(6,1),
(7,8),
(8,9),
(9,NULL),
(10,NULL),
(11,NULL))V(RowID,FK_RowID)),
Children AS(
SELECT V.RowID,
V.FK_RowID
FROM VTE V
WHERE V.RowID = @ID
UNION ALL
SELECT V.RowID,
V.FK_RowID
FROM Children C
JOIN VTE V ON C.RowID = V.FK_RowID),
Parents AS(
SELECT V.RowID,
V.FK_RowID
FROM VTE V
WHERE V.RowID = @ID
UNION ALL
SELECT V.RowID,
V.FK_RowID
FROM Parents P
JOIN VTE V ON P.FK_RowID = V.RowID)
SELECT RowID
FROM Children
WHERE RowID != @ID
UNION ALL
SELECT RowID
FROM Parents
WHERE RowID != @ID;