postgresql Spring test @Sql抛出“Unterminated dollar quote started. Expected terminating $$”

eagi6jfj  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(2)|浏览(544)

我正在使用一个测试类(FoodE 2 eTest)测试我的Sping Boot API,并且我有一个单独的SQL脚本文件(setup-test-schema.sql),我希望在测试开始之前运行该文件以设置模式、表和数据。
我使用PostgreSQL。

问题

当我单独运行文件时,它工作正常,但当我运行测试类时,我得到以下错误:

Unterminated dollar quote started at position 3 in SQL
DO $$ BEGIN IF EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'public') THEN DROP SCHEMA public CASCADE.
Expected terminating $$

字符串

配置文件

...
spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
spring.datasource.username=testuser
spring.datasource.password=testpass
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
...

测试类

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource(locations = "/application-test.properties")
@AutoConfigureMockMvc
@Sql(scripts = {"/migration/setup-test-schema.sql"}, executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
public class FoodE2eTest {
...
}

SQL文件

-- drop everything
DO
$$
    BEGIN
        IF EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'public') THEN
            DROP SCHEMA public CASCADE;
        END IF;
    END
$$;

CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
GRANT ALL ON SCHEMA public TO testuser;

-- create tables
CREATE TABLE public.user(
...

问题持续存在

1.当我指定语言时没有变化。

DO
$$
BEGIN
    IF EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = 'public') THEN
        DROP SCHEMA public CASCADE;
    END IF;
END;
$$ LANGUAGE PLPGSQL;


1.当我将@Sql注解移到方法级别时。

9udxz4iz

9udxz4iz1#

找到了一个解决方案,但我不知道它为什么有效。我猜Spring框架测试环境不支持双美元符号。

已修复此更改

-- drop everything
DO
'
BEGIN
    IF EXISTS (SELECT 1 FROM pg_namespace WHERE nspname = ''public'') THEN
        DROP SCHEMA public CASCADE;
    END IF;
END;
' LANGUAGE PLPGSQL;

CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
GRANT ALL ON SCHEMA public TO testuser;

-- create tables
CREATE TABLE public.user
(

字符串

vyu0f0g1

vyu0f0g12#

除了Spring框架可能存在的美元报价问题之外,还有一种更简单的方法可以使用专用的DROP SCHEMA IF EXISTS

DROP SCHEMA IF EXISTS public CASCADE;

字符串
自Postgres 8.2(=永远)起可用。不需要PL/pgSQL。另外,这更快更安全。您的原始版本允许在检查和执行DROP之间存在微小的竞争条件,并且在并发写入负载下可能偶尔会引发异常。

相关问题