JOOQ - 更新新添加的列

Posted

技术标签:

【中文标题】JOOQ - 更新新添加的列【英文标题】:JOOQ - Update newly added columns 【发布时间】:2021-11-26 15:01:52 【问题描述】:

我正在使用 JOOQ 和 Postgresql 数据库,我正在尝试将新列添加到表中,然后使用值更新这些列。这些值对应于推文的情绪。

到目前为止我的尝试(没有编译错误的那个:)是:

final String SENTIMENT_NEGATIVE = "sentiment_negative";
final String SENTIMENT_NEUTRAL  = "sentiment_neutral";
final String SENTIMENT_POSITIVE = "sentiment_positive";
final String SENTIMENT_COMPOUND = "sentiment_compound";

context.alterTable(Tweets.TWEETS).addColumnIfNotExists(SENTIMENT_NEGATIVE, DOUBLE).execute();
context.alterTable(Tweets.TWEETS).addColumnIfNotExists(SENTIMENT_NEUTRAL , DOUBLE).execute();
context.alterTable(Tweets.TWEETS).addColumnIfNotExists(SENTIMENT_POSITIVE, DOUBLE).execute();
context.alterTable(Tweets.TWEETS).addColumnIfNotExists(SENTIMENT_COMPOUND, DOUBLE).execute();

// example usage
for (Record record: tweetsResult) 
    String tweet = record.get(Tweets.TWEETS.CONTENT);
    SentimentAnalyzer sentimentAnalyzer = new SentimentAnalyzer(tweet);
    sentimentAnalyzer.analyze();
    log.debug(sentimentAnalyzer.getPolarity() + " | " + tweet);

    context.update(Tweets.TWEETS)
        .set(
            row(SENTIMENT_NEGATIVE,
               SENTIMENT_NEUTRAL,
               SENTIMENT_POSITIVE,
               SENTIMENT_COMPOUND),
            row(getPolarity(sentimentAnalyzer, SENTIMENT_NEGATIVE),
                getPolarity(sentimentAnalyzer, SENTIMENT_NEUTRAL),
                getPolarity(sentimentAnalyzer, SENTIMENT_POSITIVE),
                getPolarity(sentimentAnalyzer, SENTIMENT_COMPOUND))
            )
        .where(Tweets.TWEETS.ID.eq(record.get(Tweets.TWEETS.ID)))
        .execute();

但我得到一个错误:

线程 "main" org.jooq.exception.DataAccessException 中的异常:SQL [update "public"."tweets" set (?, ?, ?, ?) = row (?, ?, ?, ?) where "公开"."推文"."id" = ?];错误:“$1”处或附近的语法错误

我知道我可以根据 db schema 的变化重新生成我的源代码,但是我想知道是否可以使用我的方法来做到这一点。

【问题讨论】:

ALTER TABLE 执行后无法重新生成代码有什么原因吗? 这是一项学校作业,我需要它在其他设备上始终如一地运行,因此最好从另一台计算机重建,而无需在版本、配置和不同运行之间切换。 但是您的开发版本已经知道新列,那么为什么不至少让您的开发版本处理生成的代码呢?如果需要,您仍然可以应用迁移... 我不知道我是否理解正确 - 你需要使用我刚刚创建的列(但尚未生成)。编辑:如果再生是唯一的方法,我可以使用它,我只需要知道是否有更好的方法:) 更好的方法,相信我。我提供了一些链接的答案 【参考方案1】:

理想情况下,您将实现查询逻辑和迁移逻辑的更清晰的分离。 Flyway 或 Liquibase 等数据库更改管理工具将帮助您维护架构,并在应用程序启动时应用增量。

一旦您使用了数据库变更管理软件,您也可以在开发过程中使用它,例如通过始终将增量应用于测试容器中的开发数据库,​​然后从中重新生成代码,请参阅

A jOOQ / testcontainers / Flyway example The manual's jOOQ / Flyway tutorial

这样,您生成的代码始终是最新的,您不必使用临时类型不安全的String 表示最新列。

【讨论】:

我现在理解了代码生成背后的逻辑,并且可以更好地使用最新的类。谢谢你的澄清

以上是关于JOOQ - 更新新添加的列的主要内容,如果未能解决你的问题,请参考以下文章

SqlAlchemy 将新字段添加到类并在表中创建相应的列

在更新语句中排除空列 - JOOQ

如何在 JOOQ 中公开新的 SQL 函数

如何在JOOQ中公开新的SQL函数

AWS DMS 添加新列以跟踪更改

jOOQ 是不是支持在 SQL 语句上添加名称?