简体   繁体   English

我是否需要为DBIx :: Class belongs_to关系手动创建索引

[英]Do I need to manually create indexes for a DBIx::Class belongs_to relationship

I'm using the DBIx::Class modules for an ORM approach to an application I have. 我正在使用DBIx::Class模块来实现我的应用程序的ORM方法。

I'm having some problems with my relationships. 我的人际关系有些问题。

I have the following 我有以下内容

package MySchema::Result::ClusterIP;
use strict;
use warnings;

use base qw/DBIx::Class::Core/;

our $VERSION = '1.0';

__PACKAGE__->load_components(qw/InflateColumn::Object::Enum Core/);
__PACKAGE__->table('cluster_ip');

__PACKAGE__->add_columns( # Columns here );

__PACKAGE__->set_primary_key('objkey');
__PACKAGE__->belongs_to( 'configuration' => 'MySchema::Result::Configuration', 'config_key');
__PACKAGE__->belongs_to( 'cluster' => 'MySchema::Result::Cluster',
                            { 'foreign.config_key' => 'self.config_key',
                              'foreign.id'         => 'self.cluster_id'
                            }
                        );

As well as 以及

package MySchema::Result::Cluster;
use strict;
use warnings;

use base qw/DBIx::Class::Core/;

our $VERSION = '1.0';

__PACKAGE__->load_components(qw/InflateColumn::Object::Enum Core/);
__PACKAGE__->table('cluster');

__PACKAGE__->add_columns(  # Columns here );
__PACKAGE__->set_primary_key('objkey');
__PACKAGE__->belongs_to( 'configuration' => 'MySchema::Result::Configuration', 'config_key');
__PACKAGE__->has_many('cluster_ip'  => 'MySchema::Result::ClusterIP',
                            { 'foreign.config_key' => 'self.config_key',
                              'foreign.cluster_id' => 'self.id'
                            });

There are a couple of other modules, but I don't believe that they are relevant. 还有其他几个模块,但我不相信它们是相关的。

When I attempt to deploy this schema, I get the following error: 当我尝试部署此架构时,出现以下错误:

DBIx::Class::Schema::deploy(): DBI Exception: DBD::mysql::db do failed: Can't create table 'test.cluster_ip' (errno: 150) [
for Statement "CREATE TABLE `cluster_ip` (
  `objkey` smallint(5) unsigned NOT NULL auto_increment,
  `config_key` smallint(5) unsigned NOT NULL,
  `cluster_id` char(16) NOT NULL,
  INDEX `cluster_ip_idx_config_key_cluster_id` (`config_key`, `cluster_id`),
  INDEX `cluster_ip_idx_config_key` (`config_key`),
  PRIMARY KEY (`objkey`),
  CONSTRAINT `cluster_ip_fk_config_key_cluster_id` FOREIGN KEY (`config_key`, `cluster_id`) REFERENCES `cluster` (`config_key`, `id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `cluster_ip_fk_config_key` FOREIGN KEY (`config_key`) REFERENCES `configuration` (`config_key`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB"] at test_deploy.pl line 18

 (running "CREATE TABLE `cluster_ip` (
  `objkey` smallint(5) unsigned NOT NULL auto_increment,
  `config_key` smallint(5) unsigned NOT NULL,
  `cluster_id` char(16) NOT NULL,
  INDEX `cluster_ip_idx_config_key_cluster_id` (`config_key`, `cluster_id`),
  INDEX `cluster_ip_idx_config_key` (`config_key`),
  PRIMARY KEY (`objkey`),
  CONSTRAINT `cluster_ip_fk_config_key_cluster_id` FOREIGN KEY (`config_key`, `cluster_id`) REFERENC
ES `cluster` (`config_key`, `id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `cluster_ip_fk_config_key` FOREIGN KEY (`config_key`) REFERENCES `configuration` (`conf
ig_key`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB") at test_deploy.pl line 18

From what I can tell, MySQL is complaining about the FOREIGN KEY constraint, in particular, the REFERENCE to ( config_key , id ) in the cluster table. 据我所知,MySQL正在抱怨FOREIGN KEY约束,特别是cluster表中的( config_keyid )REFERENCE。 From my reading of the MySQL documentation, this seems like a reasonable complaint, especially in regards to the third bullet point on this doc page . 从我阅读MySQL文档来看,这似乎是一个合理的抱怨,特别是关于本文档页面的第三个要点。

Here's my question. 这是我的问题。 Am I missing something in the DBIx::Class module? 我在DBIx::Class模块中遗漏了什么? I realize that I could explicitly create the necessary index to match up with this foreign key constraint, but that seems to be repetitive work. 我意识到我可以显式创建必要的索引来匹配这个外键约束,但这似乎是重复的工作。 Is there something I should be doing to make this occur implicitly? 我是否应该采取措施使其隐含发生?

Not sure what is happening here as SQL::Translator::Producer::MySQL should insert SET foreign_key_checks=0 at the start of the deployed DDL so no foreign key errors should occur. 不确定这里发生了什么,因为SQL :: Translator :: Producer :: MySQL应该在部署的DDL的开头插入SET foreign_key_checks=0 ,这样就不会发生外键错误。 I suspect something is broken even after the whole DDL is deployed. 我怀疑即使在部署了整个DDL之后某些东西也被破坏了。 You can find out the exact nature of the foreign key error by connecting to the DB and running this statement: 您可以通过连接到DB并运行此语句来找出外键错误的确切性质:

SHOW INNODB STATUS;

I just fixed this same problem by adding the following into my result classes that were causing problems: 我刚刚通过将以下内容添加到导致问题的结果类中来解决了同样的问题:

sub sqlt_deploy_hook {
   my ($self, $sqlt_table) = @_;
   $sqlt_table->add_index(name => 'idx_my_column', fields => ['my_column']);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM