在DBIx-Class中使用预取时,如何仅选择特定列?

时间:2013-11-05 10:16:56

标签: perl catalyst dbix-class

我正在努力使用相当基本的DBIx-Class预取用法。我想限制使用预取时从连接表返回的列。

此:

my $rs = $schema->resultset('CD')->search(
  {}, # No searching restrictions through WHERE clause
  {
    prefetch => [qw/ artist /],
    columns  => [qw/ title artist.name /],
  }
);

生成此SQL:

SELECT cd.title, artist.*
FROM cd
JOIN artist ON cd.artist = artist.id

但我不想拖延所有的艺术家专栏,只需要cd.title和artist.name列(在这个例子中,我的实际用例更复杂)。列功能似乎只适用于主表而不是连接表。

我想要这个SQL:

SELECT cd.title, artist.name
FROM cd
JOIN artist ON cd.artist = artist.id

我只是在使用Catalyst / DBIx-Class进行海运,所以我可能会看到一些非常明显的东西!

3 个答案:

答案 0 :(得分:3)

是的,你是对的。您只能在主表中选择列,并且无法在连接表中获取特定列。 你需要的是加入。使用join和'+ select','+ as'属性,您可以从两个表中选择特殊列。

Prefetch也用于从预取表中选择所有列。在实际需要这些列时使用预取更有效,例如:所以你可以做$ cd-> artist-> name而不需要它来做额外的查询。但是,如果您不需要这些列,那么加载该数据会产生不必要的性能损失。

答案 1 :(得分:2)

DBIx::Class的{​​p> Version 0.08250支持预取列的子集。现在,您可以使用joincolumns以及与prefetch类似的新collapse属性编写查询:

my $rs = $schema->resultset('CD')->search(
  {},
  {
    join     => [qw/ artist /],
    columns  => [qw/ title artist.name /],
    collapse => 1,
  }
);

答案 2 :(得分:1)

附加。如果要为嵌套连接指定列(深度为2级或更多),则需要使用哈希格式指定列,以便DBIx可以解析要应用于列的关系。

示例:

    my $rs = $schema->resultset('CD')->search(
      {},
      {
        join     => { 'artist' => { 'agent' => 'publisher' } },
        columns  => [qw/ title artist.name artist.agent.publisher_id /, 
                        { 'artist.agent.publisher.publisher_name' => 'publisher.publisher_name' } ],
        collapse => 1,
      }
    );