2016-08-31 245 views
0

我更新了我的應用程序到grails 3.1.9,並且我在數據庫遷移插件時遇到了問題。grails 3數據庫遷移

我生產application.yml看起來是這樣的:

production: 
     dataSource: 
       driverClassName: org.postgresql.Driver 
       dialect: org.hibernate.dialect.PostgreSQLDialect 
       dbCreate: none 
       url: jdbc:postgresql://localhost:5432/something 
       username: postgres 
       password: postgres 
       properties: 

我的build.gradle看起來是這樣的:

buildscript { 
dependencies { 
     classpath 'org.grails.plugins:database-migration:2.0.0.RC4' 
    } 
} 

    dependencies { 
     compile 'org.liquibase:liquibase-core:3.4.1' 
     compile 'org.grails.plugins:database-migration:2.0.0.RC4' 
    } 

這是更改日誌的開頭:

databaseChangeLog = { 

    changeSet(author: "michal (generated)", id: "1472650791344-1") { 
     createTable(tableName: "appointment") { 
      column(autoIncrement: "true", name: "id", type: "BIGINT") { 
       constraints(primaryKey: "true", primaryKeyName: "appointmentPK") 
      } 

      column(name: "version", type: "BIGINT") 

      column(name: "customer_id", type: "BIGINT") 

      column(name: "duration", type: "BLOB(255)") 

      column(name: "note", type: "CLOB") 

      column(defaultValueComputed: "0", name: "personal_available", type: "BOOLEAN") 

      column(defaultValueComputed: "0", name: "personal_booked", type: "BOOLEAN") 

      column(name: "provider_id", type: "BIGINT") 

      column(name: "start_time", type: "BLOB(255)") 

      column(name: "url", type: "VARCHAR(255)") 
     } 
    } 

當我在生產模式下運行我的應用程序時,出現此錯誤。

SEVERE 8/31/16 3:41 PM: liquibase: changelog.groovy: changelog.groovy::1472650791344-1::michal (generated): Change Set changelog.groovy::1472650791344-1::michal (generated) failed. Error: ERROR: relation "appointment" already exists [Failed SQL: CREATE TABLE public.appointment (id BIGSERIAL NOT NULL, version BIGINT, customer_id BIGINT, duration BYTEA, note TEXT, personal_available BOOLEAN DEFAULT 0, personal_booked BOOLEAN DEFAULT 0, provider_id BIGINT, start_time BYTEA, url VARCHAR(255), CONSTRAINT "appointmentPK" PRIMARY KEY (id))] 
liquibase.exception.DatabaseException: ERROR: relation "appointment" already exists [Failed SQL: CREATE TABLE public.appointment (id BIGSERIAL NOT NULL, version BIGINT, customer_id BIGINT, duration BYTEA, note TEXT, personal_available BOOLEAN DEFAULT 0, personal_booked BOOLEAN DEFAULT 0, provider_id BIGINT, start_time BYTEA, url VARCHAR(255), CONSTRAINT "appointmentPK" PRIMARY KEY (id))] 
    at liquibase.executor.jvm.JdbcExecutor$ExecuteStatementCallback.doInStatement(JdbcExecutor.java:316) 

...

Caused by: org.postgresql.util.PSQLException: ERROR: relation "appointment" already exists 

我將不勝感激任何想法,爲什麼它不工作。


謝謝Gregor Petkin。設置dbcreate來驗證確實幫助我解決了這個錯誤。

+0

如果你明確地將'dbCreate'設置爲'validate'而不是'none',它有幫助嗎? –

+0

@Gregor Petrin你好,它似乎有幫助。看我的編輯。 –

回答

2

的問題是你dbCreate條款和行爲的一個非常不方便的變化導致被忽略無效dbCreate值。如果您不希望Hibernate混淆數據庫並干擾數據庫遷移,請使用dbCreate: validate

插件可以爲Grails應用程序提供值,以便它們可以提供合理的默認值,並且它可以從頭開始工作:首先逐個插件,最後application.yml有機會覆蓋他們設置的任何內容。爲了便於開發和測試,插件也是獨立的Grails應用程序,所以它們中的很多應用程序都會有一個dbCreate集。

的不便更改,發生的情況是,現在的無效dbCreate選項將獲得覆蓋由留在那裏值之前忽略了最近,隨機選擇的插件有過貢獻的配置(該插件的機會,還不如很好地使用create-drop,即使在開發環境中也可能非常不方便 - 實際上,較新的Grails版本將忽略來自插件的dbCreate設置,因爲當前行爲非常危險)。

因此,現在當數據庫遷移運行時,Hibernate已經使用updatecreate-drop設置來創建表,因此數據庫遷移失敗。配置值爲validate應該提供一個有效的替代方案來覆蓋插件所設置的任何內容。

1

似乎有點奇怪,表已經存在,但我昨晚在dev環境中遇到過這樣的事情,所以我知道它可能發生。例如,即使您有dbCreate: none,也可能由於錯誤而執行了hbm2ddl遷移工具。檢查日誌。

或者您的databasechangelog表可能由於某種原因被意外清除。檢查數據庫更新日誌表中是否有相應的特定變更集行。

對於此特定變更集,您可以做的一件事是向變更集添加tableExists前提條件並使用onFail="MARK_RAN"將變更集標記爲EXECUTED(如果該表已存在)。 Liquibase的作者曾寫道,由於性能問題,應該謹慎使用前提條件。因此,如果您發現自己爲每個更改集創建了前提條件,則可能需要重新考慮。

關於這一點,如果你收到此錯誤的更多的變更,你可能需要使用dbm-changelog-synchttp://grails-plugins.github.io/grails-database-migration/1.4.0/ref/Maintenance%20Scripts/dbm-changelog-sync.html)爲「執行」,實質上是告訴Liquibase對服務器的後續重新啓動這些變更過程中忽略它們,以紀念所有的變更。

如果您確實需要執行某些變更集(並且未被忽略) - 例如,您最近做了一些更改 - 那麼您可以使用上下文標記「要被忽略的」變更集然後使用這些值作爲context參數運行dbm-changelog-sync命令。

有關更多信息,請參閱以下鏈接。 * http://grails-plugins.github.io/grails-database-migration/1.4.0/ref/Maintenance%20Scripts/dbm-changelog-sync.html * http://www.liquibase.org/2014/11/contexts-vs-labels.html