2017-01-06 30 views
1

一差旅费必须在支付 售票其成本中心的信息,并支付了差旅费成本中心。Rails 5 - 如何将外键迁移到PostgreSQL?

我已经跑了,下面的迁移,试图创建两个外键映射到cost_centers,这对于SQLite的工作得很好:

def change 
    add_reference :expense_travels, :air_ticket_cost_center, index: true 
    add_reference :expense_travels, :travel_cost_center, index: true 

    add_foreign_key :expense_travels, :cost_centers, column: :air_ticket_cost_center_id 
    add_foreign_key :expense_travels, :cost_centers, column: :travel_cost_center_id 
    end 

然而,这不适用于工作PostgreSQL的

rake aborted! 
StandardError: An error has occurred, this and all later migrations canceled: 
PG::UndefinedTable: ERROR: relation "air_ticket_cost_centers" does not exist 
: CREATE TABLE "expense_travels" ("id" serial primary key, "expense_id" integer, "person_id" integer, "manager" character varying, "travel_type_id" integer, "air_ticket_amount" decimal(15,2), "air_ticket_cost_center_id" integer, "travel_amount" decimal(15,2), "travel_cost_center_id" integer, "total_amount" decimal(15,2), "start_date" date, "end_date" date, "itinerary" text, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_51368cd47f" 
FOREIGN KEY ("expense_id") 
REFERENCES "expenses" ("id") 
, CONSTRAINT "fk_rails_4c8cafa3f7" 
FOREIGN KEY ("person_id") 
REFERENCES "people" ("id") 
, CONSTRAINT "fk_rails_41906a97fa" 
FOREIGN KEY ("travel_type_id") 
REFERENCES "travel_types" ("id") 
, CONSTRAINT "fk_rails_c4144cce64" 
FOREIGN KEY ("air_ticket_cost_center_id") 
REFERENCES "air_ticket_cost_centers" ("id") 
, CONSTRAINT "fk_rails_8d209073b1" 
FOREIGN KEY ("travel_cost_center_id") 
REFERENCES "travel_cost_centers" ("id") 
) 

它试图设置FOREIGN KEY( “air_ticket_cost_center_id ”)作为“ air_ticket_cost_centers ”(“ ID”)的REFERENCE,这应该是一个参考cost_centers代替。

TLDR:在PostgreSQL上,以引用同现有的表两次没有冲突的另一个表,我该怎么设置我的移民?

在此先感谢!

UPDATE - 包括完整的堆栈跟踪

== 20170109120056 AddCostCentersToExpenseTravels: migrating =================== 
-- add_column(:expense_travels, :air_ticket_cost_center_id, :integer) 
    -> 0.0014s 
-- add_column(:expense_travels, :travel_cost_center_id, :integer) 
    -> 0.0007s 
-- add_foreign_key(:expense_travels, :cost_centers, {:column=>:air_ticket_cost_center_id}) 
    -> 0.0000s 
-- add_foreign_key(:expense_travels, :cost_centers, {:column=>:travel_cost_center_id}) 
    -> 0.0000s 
-- add_index(:expense_travels, :air_ticket_cost_center_id) 
    -> 0.0030s 
-- add_index(:expense_travels, :travel_cost_center_id) 
    -> 0.0033s 
== 20170109120056 AddCostCentersToExpenseTravels: migrated (0.0091s) ========== 

    db:schema:dump --> 0.250000 0.010000 0.260000 ( 0.267062) 
    db:_dump --> 0.250000 0.010000 0.260000 ( 0.267429) 
    db:migrate --> 0.710000 0.070000 0.780000 ( 1.101759) 
    db:abort_if_pending_migrations --> 0.040000 0.010000 0.050000 ( 0.040145) 
    db:seed --> 0.170000 0.020000 0.190000 ( 0.215987) 
rake aborted! 
StandardError: An error has occurred, this and all later migrations canceled: 

PG::UndefinedTable: ERROR: relation "air_ticket_cost_centers" does not exist 
: CREATE TABLE "expense_travels" ("id" serial primary key, "expense_id" integer, "person_id" integer, "manager" character varying, "travel_type_id" integer, "air_ticket_amount" decimal(15,2), "air_ticket_cost_center_id" integer, "travel_amount" decimal(15,2), "travel_cost_center_id" integer, "total_amount" decimal(15,2), "start_date" date, "end_date" date, "itinerary" text, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_51368cd47f" 
FOREIGN KEY ("expense_id") 
    REFERENCES "expenses" ("id") 
, CONSTRAINT "fk_rails_4c8cafa3f7" 
FOREIGN KEY ("person_id") 
    REFERENCES "people" ("id") 
, CONSTRAINT "fk_rails_41906a97fa" 
FOREIGN KEY ("travel_type_id") 
    REFERENCES "travel_types" ("id") 
, CONSTRAINT "fk_rails_c4144cce64" 
FOREIGN KEY ("air_ticket_cost_center_id") 
    REFERENCES "air_ticket_cost_centers" ("id") 
, CONSTRAINT "fk_rails_8d209073b1" 
FOREIGN KEY ("travel_cost_center_id") 
    REFERENCES "travel_cost_centers" ("id") 
) 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `async_exec' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `block in execute' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract_adapter.rb:566:in `block in log' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.1/lib/active_support/notifications/instrumenter.rb:21:in `instrument' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract_adapter.rb:560:in `log' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/postgresql/database_statements.rb:97:in `execute' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:283:in `create_table' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:845:in `block in method_missing' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:814:in `block in say_with_time' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:814:in `say_with_time' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:834:in `method_missing' 
/home/yadayada/workspace/yadayada/sources/db/migrate/20161201174226_create_expense_travels.rb:3:in `change' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:788:in `exec_migration' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:772:in `block (2 levels) in migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:771:in `block in migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:398:in `with_connection' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:770:in `migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:950:in `migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1211:in `block in execute_migration_in_transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1279:in `block in ddl_transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `block in transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/transaction.rb:189:in `within_new_transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/connection_adapters/abstract/database_statements.rb:232:in `transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/transactions.rb:211:in `transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1279:in `ddl_transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1210:in `execute_migration_in_transaction' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1183:in `block in migrate_without_lock' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1182:in `each' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1182:in `migrate_without_lock' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1131:in `block in migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1298:in `with_advisory_lock' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1131:in `migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:1005:in `up' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/migration.rb:983:in `migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/tasks/database_tasks.rb:161:in `migrate' 
/usr/local/rvm/gems/ruby-2.3.0/gems/activerecord-5.0.0.1/lib/active_record/railties/databases.rake:58:in `block (2 levels) in <top (required)>' 
/usr/local/rvm/gems/ruby-2.3.0/gems/rake-benchmark-1.0.0/lib/rake/benchmark.rb:8:in `block in execute_with_benchmark' 
/usr/local/rvm/gems/ruby-2.3.0/gems/rake-benchmark-1.0.0/lib/rake/benchmark.rb:7:in `execute_with_benchmark' 
/usr/local/rvm/gems/ruby-2.3.0/gems/rake-11.3.0/exe/rake:27:in `<top (required)>' 
/usr/local/rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `eval' 
/usr/local/rvm/gems/ruby-2.3.0/bin/ruby_executable_hooks:15:in `<main>' 
+0

让我看看是否明白:您需要的是您的expense_travels表中的2个新列(air_ticket_cost_center_id,travel_cost_center_id)。这两个列都必须对表cost_centers具有索引和FK约束。那是对的吗? –

+0

这完全正确@DarioBarrionuevo –

回答

1

句子add_reference :expense_travels, :air_ticket_cost_center将尝试找到一个名为expense_travels表,另一个名为air_ticket_cost_center,然后在它们之间创建一个参考。这就是为什么你会得到关系“air_ticket_cost_centers”不存在

让我们试试这个:

add_reference :expense_travels, :air_ticket_cost_center, table: :cost_centers, index: true 
add_reference :expense_travels, :travel_cost_center, table: :cost_centers, index: true 

add_foreign_key :expense_travels, :cost_centers, column: :air_ticket_cost_center_id 
add_foreign_key :expense_travels, :cost_centers, column: :travel_cost_center_id 

如果仍然不行,你不能出差错通过拆分步骤:

add_column :expense_travels, :air_ticket_cost_center_id, :integer 
add_column :expense_travels, :travel_cost_center_id, :integer 

add_foreign_key :expense_travels, :cost_centers, column: :air_ticket_cost_center_id 
add_foreign_key :expense_travels, :cost_centers, column: :travel_cost_center_id 

add_index :expense_travels, :air_ticket_cost_center_id 
add_index :expense_travels, :travel_cost_center_id 
+0

你好Dario!我尝试了两种方法,但它仍然导致我出现同样的错误:(在第二种方法中,我还将_id添加到了add_column语句中。我不知道为什么它寻找具有相同的表列的名称,而不是表格,我们将它们专门分配给 –

+1

当然,使用'add_column'语句添加的列必须是_id,我编辑了我的答案。您是否确定在此特定迁移中引发了错误?如果运行迁移的第二个版本,Postgres应该能够创建列,那么在添加外键时,哪里会出现错误? –

+0

确切地说,这些字段是正常创建的:问题在约束分配期间弹出,试图将“air_ticket_cost_centers”作为表格引用,即使它在迁移过程中从未被提及过,就像字段中带有“_id”一样。看起来它试图迫使这个领域成为一个惯例或者某个东西,我在这里真正地脱离了想法。这是AR本身的问题吗?你最近做了些什么?我读过它在SQLite上的工作原理,因为“SQLite不像FKs上的PG那么严格”,这对我来说根本没有任何意义。 –