H2 - Postgres 模式支持网络数据类型
Posted
技术标签:
【中文标题】H2 - Postgres 模式支持网络数据类型【英文标题】:H2 - Postgres mode support net data type 【发布时间】:2020-03-16 18:12:58 【问题描述】:我有一个 DAO 正在访问 Postgres 数据库。我想将 H2 用于我的单元测试 - 一切都很好,除了我正在操作的表有一个带有 inet
数据类型的列 - 所以我得到了例外
未知数据类型:“inet”; SQL 语句:从表中删除 id = ?和 ip_address = ?::inet [50004-200]
自从我使用 H2 以来已经有一段时间了 - 我已经为连接设置了 Postgres 模式:url jdbc:h2:mem:test;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE
我是否可以在 H2 中执行此查询并支持此数据类型?
【问题讨论】:
考虑使用类似 testcontainers-java 的 postgresql 模块,而不是尝试使用不同的数据库进行单元测试。 @MarkRotteveel 太棒了,谢谢。我尝试了 zonky 嵌入式 Postgres,但它无法在 Jenkins 上构建,并且该项目没有提供任何可操作的输出,因此没有关于哪里出了问题的指导。测试容器完美运行。您能否将其发布为答案,以便我接受它 【参考方案1】:H2 提供的兼容模式并不完美,它们不能 100% 覆盖所有功能,也不能提供 100% 相同的行为。
我建议您使用PostgreSQL module of testcontainers-java,而不是在您的单元测试中使用不同的数据库,并尝试使其尽可能接近(然后被生产中的差异所困扰)。这允许您为单元测试启动 PostgreSQL docker 映像。
请注意,这会影响性能,因为它可能会比使用 H2 慢一些,因为需要启动 docker 映像。我建议仔细考虑您的测试是否真的需要进入数据库,或者可以摆脱模拟数据,或者至少限制(需要)进入数据库的测试范围。
【讨论】:
工作就像一个魅力 - 我立即注意到时间开销,但这将存在于功能测试层中,因此它不应该太具有破坏性【参考方案2】:这里最大的问题是您的未知数据类型的表是如何创建的?列 ip_address
应该有一些 H2 已知的其他数据类型。
其实你可以这样创建一个域:
CREATE DOMAIN INET AS VARCHAR;
但是在任何地方都使用相同的数据库系统会更好。
【讨论】:
create table myTable ( ip_address inet, id INT NOT NULL)
是用于创建表的sql - 导致Unknown data type: "inet"; SQL statement
错误
我在上面的表创建之前运行了create domain inet as varchar
并遇到了同样的错误——因为 create 的返回是假的——必须弄清楚该命令失败的原因
create domain inet as varchar; create table myTable ( ip_address inet, id INT NOT NULL);
在 H2 中完成,没有任何异常。
我希望我也有同样的运气。我正在使用 Scalike JDBC - using(inMemoryPool.borrow()) conn => val db: DB = DB(conn) db.localTx implicit session => val inetCreated = sql"""create domain inet as varchar""".execute().apply() println(inetCreated) // false sql"""create table mytable ( ip_address inet, id INT NOT NULL)""".execute.apply()
-- 域创建结果为假,后续创建表失败
使用纯 JDBC 和在 H2 控制台中一切正常,但我无法帮助您使用您使用的包装器;我不熟悉它。以上是关于H2 - Postgres 模式支持网络数据类型的主要内容,如果未能解决你的问题,请参考以下文章