错误1833:无法更改列ID

时间:2014-10-29 10:16:29

标签: mysql symfony pdo doctrine-orm alter-table

使用prompt命令,我使用逆向工程生成了一个带有doctine的数据库。它运作得很好:

php app/console doctrine:mapping:convert yml ./src/Gir/DatabaseBundle/Resources/config/doctrine/metadata/orm --from-database --force

之后,我创建实体

php app/console doctrine:mapping:import GirDatabaseBundle annotation

注释

php app/console doctrine:generate:entities GirDatabaseBundle

然后,我用composer.phar安装了Symfony的新更新。

然后, FOSUserBundle 以管理我项目中的用户。

我必须使用此提示命令使用 doctrine 更新我的数据库,以便生成表用户和实体等:

php app/console doctrine:schema:update --force

当我执行此命令时,doctrine会在Windows提示符命令中将此错误发送给我:

**[Doctrine\DBAL\DBALException]**
An exception occured while executing 'ALTER TABLE agence CHANGE id id INT NOT NULL':
SQLSTATE[HY000]: General error: 1833 Cannot change colum 'id': used in a foreign key constraint 'fk_employe_agence1' of table 'gir.employe'

**[PDOException]**
SQLSTATE[HY000]: General error: 1833 Cannot change colum 'id': used in a foreign key constraint 'fk_employe_agence1' of table 'gir.employe'

这是 agence 表的SQL:

--
-- Base de données :  `gir`
--

-- --------------------------------------------------------

--
-- Structure de la table `agence`
--

CREATE TABLE IF NOT EXISTS `agence` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(150) NOT NULL,
  `nomVoie` varchar(150) NOT NULL,
  `numVoie` int(5) DEFAULT NULL,
  `codePostal` int(5) NOT NULL,
  `comune` varchar(150) NOT NULL,
  `telephone` varchar(150) NOT NULL,
  `fax` varchar(150) NOT NULL,
  `email` varchar(150) NOT NULL,
  `entreprises_id` int(11) NOT NULL,
  PRIMARY KEY (`id`,`entreprises_id`),
  KEY `fk_agence_entreprises1_idx` (`entreprises_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

这是员工表的SQL:

--
-- Base de données :  `enexgir`
--

-- --------------------------------------------------------

--
-- Structure de la table `employe`
--

CREATE TABLE IF NOT EXISTS `employe` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(45) NOT NULL,
  `prenom` varchar(45) NOT NULL,
  `poste` varchar(45) NOT NULL,
  `portable` varchar(45) NOT NULL,
  `ligneDirecte` varchar(45) NOT NULL,
  `faxDirect` varchar(45) NOT NULL,
  `email` varchar(150) NOT NULL,
  `etat` tinyint(1) NOT NULL,
  `agence_id` int(11) NOT NULL,
  PRIMARY KEY (`id`,`agence_id`),
  KEY `fk_employe_agence1_idx` (`agence_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

--
-- Contraintes pour les tables exportées
--

--
-- Contraintes pour la table `employe`
--
ALTER TABLE `employe`
  ADD CONSTRAINT `fk_employe_agence1` FOREIGN KEY (`agence_id`) REFERENCES `agence` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

有人应该为什么以及如何用学说来解决这个问题?

3 个答案:

答案 0 :(得分:4)

外键的问题是Doctrine有时无法解决它们。但它通常可以暂时禁用FK。请尝试以下方法:

准备一个SQL转储,它将在导入期间禁用FK检查。然后告诉Doctrine将更改转储到文件中,而不是直接应用它们。然后用MySQL导入文件。

# disable FK checks during the import
echo 'SET FOREIGN_KEY_CHECKS = 0;' > dump.sql

# append the DB dump
app/console doctrine:schema:update --dump-sql --complete >> dump.sql

# import the dump into MySQL
mysql -u username -p -D dbname < dump.sql

如果这样做没有抛出错误,请让Doctrine检查一切是否与ORM定义一致:

app/console doctrine:schema:update --dump-sql --complete

如果这样可以让您执行更多SQL查询,那么就这样做。在那之后,你应该没事。

答案 1 :(得分:1)

此解决方案是正确的:https://stackoverflow.com/a/26628581/2400373

但是如果您使用Symfony 3,那么正确的是:

bin/console doctrine:schema:update --dump-sql --complete >> dump.sql

在此说明之前从未使用过php指令。

答案 2 :(得分:0)

如果您想将此作为DataFixture使用,请参阅加载方法中的方法:

    $dumpFilePath  = "dump.sql";
    file_put_contents($dumpFilePath, "SET FOREIGN_KEY_CHECKS = 0; \n");

    $kernel = $this->container->get('kernel');
    $application = new Application($kernel);
    $application->setAutoExit(false);
    $options = array('command' => 'doctrine:schema:update', '--dump-sql' => true, '--complete' => true);

    $input = new ArrayInput($options);
    $output = new StreamOutput(fopen($dumpFilePath, 'a'));
    $application->run($input, $output);

    $entityManager->getConnection()->prepare(file_get_contents($dumpFilePath))->execute();