Rails Postgresql多个模式和相同的表名

7
我有两张表在不同的模式下,例如 casesevents
每个模式下我都有一个表basic:
- events.basic - cases.basic 这些表之间存在关联关系:
- events.basiccases.basic有一对多的关系(cases.basic拥有多个events.basic
我的尝试失败了:
文件cases_basic.rb
class CasesBasic < ActiveRecord::Base
  set_table_name 'cases.basic'
  set_primary_key 'case_id'
  has_many :Events, :class_name => 'EventsBasic', :foreign_key => 'case_id'
end

file events_basic.rb

class EventsBasic < ActiveRecord::Base
  set_table_name 'events.basic'
  set_primary_key 'event_id'
  belongs_to :Case, :class_name => 'CasesBasic', :foreign_key => 'case_id'
end

环境:

Ruby 1.9.3,Rails 3.1.3gem 'pg'

我需要回答以下问题:

  1. 如何在Rails Active Record中处理此情况?
  2. 如何查询这些表?
  3. 如何在rake db:schema:dump中处理此情况?

编辑:

按照Catcall的建议更改了belongs_tohas_many之后,我仍然遇到了相同的错误。

PGError: ERROR:  column basic.case_id does not exist
LINE 1: ...IN "cases"."basic" ON "cases"."basic"."case_id" = "events"."...
                                                             ^
: SELECT  "events"."basic".* FROM "events"."basic" INNER JOIN "cases"."basic" ON "cases"."basic"."case_id" = "events"."basic"."case_id" LIMIT 3

Rails生成的SQL语句有些问题。我应该使用一些别名:
SELECT t1.* FROM "events"."basic" t1 INNER JOIN "cases"."basic" t2 ON t1."case_id" = t2."case_id" LIMIT 3
编辑2: 好的,这是我的错误,我没有在示例数据库中添加“事件”。“基本”。“案件编号列和外键”。它可以工作!
问题1和问题2都已解决,但我们对rake db:schema:dump有一些疑问。Rails只为public模式生成模型。
我有很多表格和关系,我想生成它们。

您的:Events:Case应该改为:events:case,但这可能并不能解决问题。 - mu is too short
@muistooshort:EventsCase看起来像是别名,在这种情况下不会被传递到SQL。 - Jacek Wysocki
我对表格的样子有点困惑,ON "cases"."basic"."case_id" = "events"."basic"."case_id" 这个连接条件应该是什么样子的呢?其中一个表格没有 case_id 这个字段,这是个问题,如果你手动写这个连接条件,你会怎么写? - mu is too short
1
尝试在您的databases.yaml中设置schema_search_path: public,events,cases,然后尝试运行rake db:schema:dump - mu is too short
@muistooshort 它生成了 schema.rb,但内容有点混乱 :) - Jacek Wysocki
1
你得到了一个 schema.rb 文件,其中包含所有内容,但是没有一个表名包括 PostgreSQL 模式前缀,对吧? - mu is too short
3个回答

2

我建议使用pg_power gem。它提供了在迁移中创建PostgreSQL模式的语法,例如:

def change
  drop_schema 'demography'
  create_schema 'politics'
end

同时,它还负责将模式正确地转储到schema.rb文件中。

注意:这个宝石不再需要了,create_schema和drop_schema是Rails的PostgreSQL API的一部分。https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html - undefined

1

1
感谢您的回复,但不幸的是它并没有解决问题。作者在这里使用了“SET SEARCH_PATH TO schema1,schema2”的方法,这对于简单的数据库非常好,当您不需要在不同模式之间建立关系时,但它并不能解决多个模式的问题,您无法连接具有相同名称的表。而我的系统中有300个表,其中许多表具有相同的名称。 - Jacek Wysocki

1

[编辑:经过进一步阅读,我认为ActiveRecord根本不支持多个模式。但我可能是错的。我暂时会把这个答案留在这里,尽管它几乎肯定是错误的。(从概念上讲是正确的。但构建ActiveRecord的人可能没有与任何数据库人员交谈,因为数据库人员可能知道什么呢?)看起来IBM在2008年正在解决这个问题,但我不知道那项工作是否结束。]

PostgreSQL没有任何问题将外键引用设置到不同模式中具有相同名称的表。像这样的代码

class CasesBasic < ActiveRecord::Base
  set_table_name 'cases.basic'
  set_primary_key 'case_id'
  has_many :Events, :class_name => 'EventsBasic', :foreign_key => 'case_id'
end

可能需要模式限定。

现在,cases.basic表“有很多”事件这种说法不正确,对吧?不是的,它“有很多”events.basic。在你的两个类中进行这种更改,并告诉我们它的效果如何。(没有Rails,否则我可以为您测试。)


还有CHECK约束、函数索引、触发器以及其他MySQL3不理解的内容。 - mu is too short
将SEARCH_PATH中不想查询的模式包含/排除,是否不能解决模式内表位置的问题?此外,您可以通过在特定模式前缀中加入完全限定的表路径来查询吗? - Ben Simpson
@BenSimpson:我理解OP的情况是,search_path不会有帮助,因为每个模式都具有相同名称的表。 就像events.basic,cases.basic,other_things.basic一样。 我认为这些并不是很好的表名,这不是重点。 我目前对Rails的了解是,它不支持schema.table语法。 这就是为什么我说我的答案几乎肯定是错误的原因。 - Mike Sherrill 'Cat Recall'
@muistooshort:领域(?)。(不是Rails专家。) - Mike Sherrill 'Cat Recall'
领域?不,我不这么认为。Rails真的希望将数据库视为一个愚蠢的数据存储器,所以我们可以看到所有丑陋的PHP/MySQL风格的滥用(如果你想骂一下,看看serialize)。当然,我是一个天生的异端。 - mu is too short
显示剩余3条评论

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