我的 Rails 5.1 CI 测试开始失败,并出现以下错误:
bundle exec rake db:create db:structure:load
Created database 'my_test'
psql: .../structure.sql:72: ERROR: operator family "btree_hstore_ops" for access method "btree" already exists
rake aborted!
我正在将 Rails 应用更新到版本 5.1。
Rails 5.1 似乎对模型索引的定义方式进行了一些更改,包括将以下内容添加到 Structure.sql。
CREATE OPERATOR FAMILY btree_hstore_ops USING btree;
CREATE OPERATOR FAMILY gin_hstore_ops USING gin;
CREATE OPERATOR FAMILY gist_hstore_ops USING gist;
CREATE OPERATOR FAMILY hash_hstore_ops USING hash;
这些似乎是原因。
有人遇到过这个问题吗?有没有办法使 CREATE OPERATOR FAMILY
成为条件并检查 btree_hstore_ops
是否已存在?或者我应该寻找其他地方来解决这个问题?
编辑:
添加跟踪:
-> rake db:structure:load
Running via Spring preloader in process 78735
psql:/Users/me/code/myapp/db/structure.sql:72: ERROR: operator family "btree_hstore_ops" for access method "btree" already exists
rake aborted!
failed to execute:
psql -v ON_ERROR_STOP=1 -q -f /Users/me/code/myapp/db/structure.sql mw_development
Please check the output above for any errors and make sure that `psql` is installed in your PATH and has proper permissions.
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/postgresql_database_tasks.rb:108:in `run_cmd'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/postgresql_database_tasks.rb:80:in `structure_load'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:223:in `structure_load'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:236:in `load_schema'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:255:in `block in load_schema_current'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:305:in `block in each_current_configuration'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:302:in `each'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:302:in `each_current_configuration'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/tasks/database_tasks.rb:254:in `load_schema_current'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activerecord-5.1.5/lib/active_record/railties/databases.rake:290:in `block (3 levels) in <top (required)>'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activesupport-5.1.5/lib/active_support/dependencies.rb:286:in `load'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activesupport-5.1.5/lib/active_support/dependencies.rb:286:in `block in load'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activesupport-5.1.5/lib/active_support/dependencies.rb:258:in `load_dependency'
/Users/me/.rvm/gems/ruby-2.4.3@myapp/gems/activesupport-5.1.5/lib/active_support/dependencies.rb:286:in `load'
-e:1:in `<main>'
Tasks: TOP => db:structure:load
(See full trace by running task with --trace)
最佳答案
此问题与 Rails 无关,而是与 PostgreSQL 相关。尽管将数据库状态转储为一系列 SQL 命令是复制模式的好方法,并且 Rails 核心文档中提到了这一点,但它有点“盲目射击”,因为它假设了您的模式的清晰状态。 DB,你的情况并非如此。您面临的问题是您之前可能已经使用过数据库,并且通过这样做您可能已经创建了应用程序所需的一些运算符。如果您选择将数据库状态转储为 SQL 命令,则加载这些模式只是执行它们包含的语句的问题。根据定义,这将创建数据库结构的完美副本,但在执行之前不会检查以前的数据库状态。正如错误消息所示,您尝试执行的操作已经完成。为了避免这种情况,请将查询更改为使用 ALTER OPERATOR FAMILY ... ADD
,如下所示:
ALTER OPERATOR FAMILY btree_hstore_ops USING btree ADD
ALTER OPERATOR FAMILY gin_hstore_ops USING gin ADD
ALTER OPERATOR FAMILY gist_hstore_ops USING gist ADD
ALTER OPERATOR FAMILY hash_hstore_ops USING hash ADD
Documentation states ALTER OPERATOR FAMILY
目前不检查运算符族定义是否包含索引方法所需的所有运算符和函数,也不检查运算符和函数是否形成自洽的集合。用户有责任定义有效的运算符系列。
关于ruby-on-rails - 为什么db是:structure:load failing with "operator family "btree_hstore_ops for access method btree already exists"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48878313/