Нужно ли вручную создавать индексы для отношения DBIx :: Class own_to - PullRequest
4 голосов
/ 22 февраля 2011

Я использую модули DBIx::Class для подхода ORM к приложению, которое у меня есть.

У меня проблемы с отношениями.

У меня есть следующее

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'
                            }
                        );

Так же как и

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'
                            });

Есть несколько других модулей, но я не верю, что они актуальны.

Когда я пытаюсь развернуть этосхема, я получаю следующую ошибку:

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

Из того, что я могу сказать, MySQL жалуется на ограничение FOREIGN KEY, в частности, ОТНОСИТЕЛЬНО (config_key, id) в cluster стол.Из моего прочтения документации по MySQL это выглядит как разумная жалоба, особенно в отношении третьего пункта на странице на этой странице документа .

Вот мой вопрос.Я что-то упускаю в модуле DBIx::Class?Я понимаю, что мог бы явно создать необходимый индекс, чтобы соответствовать этому ограничению внешнего ключа, но это, кажется, повторяющаяся работа.Что-то, что я должен сделать, чтобы это произошло неявно?

Ответы [ 2 ]

3 голосов
/ 28 февраля 2011

Не уверен, что здесь происходит, так как SQL :: Translator :: Producer :: MySQL должен вставить SET foreign_key_checks=0 в начале развернутого DDL, чтобы не возникало ошибок внешнего ключа. Я подозреваю, что что-то сломано даже после того, как весь DDL развернут. Вы можете узнать точную природу ошибки внешнего ключа, подключившись к БД и выполнив следующую инструкцию:

SHOW INNODB STATUS;
0 голосов
/ 11 марта 2016

Я только что исправил эту проблему, добавив в классы результатов, которые вызывали проблемы, следующее:

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