在 PostgreSQL 数据库中插入带有 jOOQ 的 SQL 枚举
Posted
技术标签:
【中文标题】在 PostgreSQL 数据库中插入带有 jOOQ 的 SQL 枚举【英文标题】:Insert SQL enum with jOOQ in PostgreSQL database 【发布时间】:2021-08-01 21:50:00 【问题描述】:我正在尝试使用 jOOQ 在我的数据库中插入一个 SQL 枚举。
数据库迁移是使用 Liquibase 设置的,例如:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">
<changeSet id="202105031559" author="pk">
<sql>CREATE TYPE my_type AS ENUM ('TYPE_A', 'TYPE_B')</sql>
<createTable tableName="a">
<column name="type" type="my_type" defaultValue='TYPE_A'>
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
迁移中的默认枚举值按预期工作。
尝试使用jOOQ插入枚举:
var result = dslContext
.insertInto(A,
A.TYPE
)
.values(
MyType.TYPE_B
)
.execute();
触发错误:
org.postgresql.util.PSQLException: ERROR: column "type" is of type my_type but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
我的 jOOQ 配置如下所示:
@Configuration
public class JooqConfig
private final DataSource dataSource;
public JooqConfig(DataSource dataSource)
this.dataSource = dataSource;
@Bean
public DataSourceConnectionProvider connectionProvider()
return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
@Bean
public DefaultDSLContext dsl()
Settings settings = new Settings()
.withRenderNameCase(RenderNameCase.LOWER)
.withRenderQuotedNames(RenderQuotedNames.NEVER)
.withExecuteLogging(true);
return new DefaultDSLContext(connectionProvider(), SQLDialect.POSTGRES, settings);
我的 Gradle 设置:
jooq
version.set(dependencyManagement.importedProperties["jooq.version"])
edition.set(nu.studer.gradle.jooq.JooqEdition.OSS)
configurations
create("main")
jooqConfiguration.apply
generator.apply
database.apply
name = "org.jooq.meta.extensions.liquibase.LiquibaseDatabase"
withProperties(
org.jooq.meta.jaxb.Property()
.withKey("scripts")
.withValue("src/main/resources/db/changelog/changelog-ddl.xml"),
org.jooq.meta.jaxb.Property()
.withKey("includeLiquibaseTables")
.withValue("false"),
org.jooq.meta.jaxb.Property()
.withKey("database.liquibaseSchemaName")
.withValue("public"),
org.jooq.meta.jaxb.Property()
.withKey("changeLogParameters.contexts")
.withValue("!test"),
)
有人知道如何使用 jOOQ 插入枚举吗?
【问题讨论】:
【参考方案1】:从 jOOQ 3.15 开始,org.jooq.meta.extensions.liquibase.LiquibaseDatabase
将 DDL 语句转换为 H2 并模拟内存 H2 数据库上的迁移。这意味着您不能使用供应商特定的 PostgreSQL 功能(H2 支持枚举,但它们有很多缺陷)。
相反,推荐的方法是使用testcontainers 和一个实际的 PostgreSQL 数据库来生成代码。此问题中记录了有关如何执行此操作的一些想法:https://github.com/jOOQ/jOOQ/issues/6551 或在此示例中:https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples/jOOQ-testcontainers-example
【讨论】:
以上是关于在 PostgreSQL 数据库中插入带有 jOOQ 的 SQL 枚举的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 JOOQ 在 PostgreSQL 中插入带有 JSON 列的可更新记录?
带有 pg8000 的 PostgreSQL - 从 SQL 插入结果到另一个表
postgresql的copy命令如何将csv中的引号转换成null插入?