Liquibase为postgres创建模式

14

我正在使用Dropwizard(1.0.0)和Liquibase来创建一个数据库,如果它不存在的话。

问题在于,我正在使用不同的Postgres模式(不是public)。看起来Liquibase无法在创建数据库之前创建此模式。我本以为Liquibase会生成这个模式,但每次尝试构建数据库时,它总是抛出“找不到名称为xx的模式”的错误。


1
Liquibase 不会在没有你告诉它要做什么的情况下创建任何内容。你需要在你的变更日志中包含一个 create schema - user330315
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Christian
再次强调:Liquibase仅运行从更改日志定义中结果的语句。它不会有任何魔法或猜测您缺少哪些对象。它仅仅是一种编写SQL语句的结构化方式,对于您的转储文件一无所知。 - user330315
是的,我明白了。但我想知道为什么liquibase dump不会转储模式和数据库,而只转储表格... 在我看来这没有意义。 - Christian
我猜这是因为它没有“原生”支持创建模式(因为在不同的数据库管理系统之间,这非常不同)。 - user330315
1
此外,在PostgreSQL中使用多个模式是首选方案,当您的每个应用程序都有一个单独的用户拥有其(可能仅有的)模式,但不能访问其他任何模式时。在此设置中,这些用户通常没有权利甚至创建模式(并且因为他们不是超级用户,他们也无法创建扩展)。例如,无法使用该用户创建此场景,并且由于在PostgreSQL中无法在连接内切换用户,因此最好先“设置事物”,即在liquibase运行之前创建模式、扩展等。 - pozs
4个回答

15

虽然Liquibase在其捆绑的更改/重构中没有CREATE SCHEMA(因此在dropwizard的db dump期间不生成模式),但您仍可以使用sql标签将其作为迁移日志中的一个changeset包含在内,方法如下:

<changeSet author="christian" id="1">
    <sql dbms="postgresql" endDelimiter=";">
        CREATE SCHEMA foo
    </sql>
</changeSet>

请注意Liquibase将在应用任何更改集之前,在公共模式中创建自己的表:
如果您在Dropwizard中运行db migrate --dry-run,您会发现Liquibase首先会执行

CREATE TABLE PUBLIC.DATABASECHANGELOGLOCK ...
CREATE TABLE PUBLIC.DATABASECHANGELOG ...

运行之前

CREATE SCHEMA foo;

2
您可以通过 --defaultSchemaName 参数告诉 Liquibase 使用不同的模式来创建自己的表。 - user330315
3
要让这个方法起作用,模式必须先存在。等效的Dropwizard命令db migrate --schema foo在尝试创建Liquibase表时会失败,并显示“无效的模式名称”错误。 - fspinnenhirn
如果我们决定将更改日志文件用于多个数据库,比如SQL Server和Postgres,这仍然有效吗?是否可以通过dbms属性区分相同更改的两个部分? - Muthaiah PL
@fspinnenhirn,您好!请问我们能否动态地传递模式名称?例如:<property name="schemaName" value="temp2"/> <changeSet author="abcd" id="1"> <sql dbms="postgresql" endDelimiter=";"> CREATE SCHEMA $(schemaName) </sql> </changeSet> - user2359997
@fspinnenhirn 这也会是我的问题的答案吗?https://dev59.com/9cH5oIgBc1ULPQZFVCyi - Aԃιƚყα Gυɾαʋ

9

这并不是直接回答问题的答案,但我发表它是为了帮助遇到和我一样在多个模式中创建表时遇到错误的人。我在使用Maven的defaultSchemaName配置执行此操作时遇到了错误。

[ERROR] Failed to execute goal org.liquibase:liquibase-maven-plugin:3.6.2:update (default-cli) on project demo: Error setting up or running Liquibase: ERROR: relation "databasechangelog" already exists [Failed SQL: CREATE TABLE databasechangelog (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(255) NOT NULL, DATEEXECUTED TIMESTAMP WITHOUT TIME ZONE NOT NULL, ORDEREXECUTED INTEGER NOT NULL, EXECTYPE VARCHAR(10) NOT NULL, MD5SUM VARCHAR(35), DESCRIPTION VARCHAR(255), COMMENTS VARCHAR(255), TAG VARCHAR(255), LIQUIBASE VARCHAR(20), CONTEXTS VARCHAR(255), LABELS VARCHAR(255), DEPLOYMENT_ID VARCHAR(10))] -> [Help 1]

我尝试通过将以下配置添加到pom.xml来修复它,但这只是一个部分解决方案:
<defaultSchemaName>foo</defaultSchemaName>
<changelogSchemaName>foo</changelogSchemaName>

最后,我通过在连接字符串的末尾添加“foo”来解决了这个问题,像这样:jdbc:postgresql://localhost:5432/postgres?currentSchema=foo

6

Liquibase没有CREATE SCHEMA,您需要通过运行SQL查询来管理创建模式功能。

<changeSet author="liquibase_user" id="1">
    <sql>
        CREATE SCHEMA IF NOT EXISTS liquibase_demo;
    </sql>
</changeSet>

4
除了您正在使用Dropwizard之外,Spring Boot Pre-Liquibase模块可以满足您的需求。Liquibase存在一个鸡生蛋的问题,它不能用于配置自己的前提条件,例如模式。这就是Pre-Liquibase解决的问题。它在Liquibase本身之前执行一些SQL语句。有时,您希望在同一数据库主机上托管多个应用程序实例。然后,您将希望通过模式将它们分开。这只是Pre-Liquibase的一个可能用例。Pre-Liquibase适用于Spring,因此无法直接在Dropwizard场景中使用。但是请随意借鉴其中的想法。(完整披露:我是Pre-Libuibase的作者)

3
这应该被点赞100次。liquibase决定只能使用现有的模式/Keyspace(Cassandra),使其对具有多个环境和多个不同keyspace的生产级迁移无用。 - Eugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接