db:setup fails with ActiveRecord::StatementInvalid: PG::DuplicateObject
emersonthis opened this issue · comments
Describe the bug
After adding a couple migrations that use add_enum
I can no longer run rake db:setup
without the following error:
$ bundle exec rake db:setup
Database 'myapp_dev' already exists
Database 'myapp_test' already exists
rake aborted!
ActiveRecord::StatementInvalid: PG::DuplicateObject: ERROR: type "question_answer_length" already exists
/Users/emerson/Code/myapp/db/schema.rb:18:in `block in <main>'
/Users/emerson/Code/myapp/db/schema.rb:13:in `<main>'
/Users/emerson/.rbenv/versions/2.6.3/bin/bundle:23:in `load'
/Users/emerson/.rbenv/versions/2.6.3/bin/bundle:23:in `<main>'
Caused by:
PG::DuplicateObject: ERROR: type "question_answer_length" already exists
/Users/emerson/Code/myapp/db/schema.rb:18:in `block in <main>'
/Users/emerson/Code/myapp/db/schema.rb:13:in `<main>'
/Users/emerson/.rbenv/versions/2.6.3/bin/bundle:23:in `load'
/Users/emerson/.rbenv/versions/2.6.3/bin/bundle:23:in `<main>'
Tasks: TOP => db:schema:load
(See full trace by running task with --trace)
To Reproduce
Steps to reproduce the behavior:
- Added
gem 'activerecord-postgres_enum'
to Gemfile $ bundle install
- Create a couple migrations that use
add_enum
- Run
$ bundle exec rake db:setup
Expected behavior
Command runs without error.
Context (please complete the following information):
- OS: MacOS
- Version 10.15.3
Additional context
Ruby version 2.6.3p62
PostgreSQL version 12
I also tried running db:reset
first. The same error occurs.
It doesn't look like it is happened because of this gem. Please provide a bare minimum application that is representing that bug.
@bibendi I'm seeing the same thing and it happens with any Rails app I've tried that uses the Ruby DSL for the schema.
The problem appears to be that create_enum
doesn't have a corresponding :force
option like create_table
does. So, create_enum
unconditionally tries to create the enum when processing schema.rb, without dropping the old enum first. If you don't drop the database after you've run your migrations and then run db:setup
, the create_enum
call will conflict with the existing enum.
Adding on, there is support in schema.rb for a :if_not_exists
keyword option, like so:
create_enum :integration_account_state, [
"connected",
"errored",
"pending",
], if_not_exists: true
This option isn't documented and isn't set by default, which is in contrast to how ActiveRecord handles create_table
. I'd suggest that there should be a :force
option as well because :if_not_exists
won't handle the case where the enum variants change. If they change and you run db:setup
, you'll end up with the old values.
@nirvdrum, I agree with you. It looks like it needs to be implemented force: :cascade
option and enable it by default in the schema.