【问题标题】:Doctrine returns always the same record & schema:update fails教义总是返回相同的记录和模式:更新失败
【发布时间】:2015-02-05 09:17:45
【问题描述】:

我正在尝试将现有数据库与 Symfony/Doctrine 一起使用,但似乎没有任何效果。

导入(数据库到映射)成功,在 src/xxx/Entity 中生成的文件看起来不错。

但是,有两个问题:

问题

Doctrine 想在我的小得离谱的数据库上运行 13 个查询。我以为导入后,Doctrine 会与在线数据库同步。然而,事实并非如此。

如果我不修改数据库会更好(因为原因),无论如何doctrine:schema:update 完全失败:

### doctrine:schema:update --dump-sql
ALTER TABLE categorie CHANGE id id TINYINT(1) NOT NULL;
ALTER TABLE produit CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE categorie_id categorie_id TINYINT(1) DEFAULT NULL, CHANGE derniere_maj derniere_maj DATETIME NOT NULL;
DROP INDEX fk_produit_categorie1_idx ON produit;
CREATE INDEX IDX_29A5EC27BCF5E72D ON produit (categorie_id);
ALTER TABLE commande_client CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE client_id client_id INT DEFAULT NULL, CHANGE date_creation date_creation DATETIME NOT NULL, CHANGE no_confirmation no_confirmation INT NOT NULL;
DROP INDEX fk_commande_client_client1_idx ON commande_client;
CREATE INDEX IDX_C510FF8019EB6921 ON commande_client (client_id);
ALTER TABLE commande_client_vers_produit DROP quantite, CHANGE commande_client_id commande_client_id INT NOT NULL, CHANGE produit_id produit_id INT NOT NULL;
DROP INDEX fk_commande_client_has_produit_commande_client1_idx ON commande_client_vers_produit;
CREATE INDEX IDX_6E3497729E73363 ON commande_client_vers_produit (commande_client_id);
DROP INDEX fk_commande_client_has_produit_produit1_idx ON commande_client_vers_produit;
CREATE INDEX IDX_6E349772F347EFB ON commande_client_vers_produit (produit_id);
ALTER TABLE client CHANGE id id INT AUTO_INCREMENT NOT NULL;

### doctrine:schema:update --force

  [Doctrine\DBAL\Exception\DriverException]                                                                               
  An exception occurred while executing 'ALTER TABLE categorie CHANGE id id TINYINT(1) NOT NULL':                         
  SQLSTATE[HY000]: General error: 1025 Error on rename of './chezbio/#sql-1983_d2' to './chezbio/categorie' (errno: 150)  

  [Doctrine\DBAL\Driver\PDOException]                                                                                     
  SQLSTATE[HY000]: General error: 1025 Error on rename of './chezbio/#sql-1983_d2' to './chezbio/categorie' (errno: 150)  

  [PDOException]                                                                                                          
  SQLSTATE[HY000]: General error: 1025 Error on rename of './chezbio/#sql-1983_d2' to './chezbio/categorie' (errno: 150)  

为什么要进行所有这些更新?实际的数据库在理论上是正确设计的。

问题中最重要的部分:

(这可能与Doctrine无法与在线数据库同步的部分有关。)

我正在尝试select 我的表中的几行。

例如,这里我尝试从categorie 表中获取所有行:

$em->getRepository('AlembicBioBundle:Categorie')->findAll();

我在这张表中有 4 行:

mysql> SELECT * FROM categorie;
+----+----------+
| id | nom      |
+----+----------+
|  1 | FROMAGES |
|  2 | PAINS    |
|  3 | LEGUMES  |
|  4 | VIANDES  |
+----+----------+

当我使用 Doctrine 函数(而不是手动查询)时,我得到了 4 次“FROMAGES”行。 什么可能导致这个问题?

最糟糕的是当我这样做时:

$em->getRepository('AlembicBioBundle:Categorie')->findOneByNom('PAINS');

它返回这些结果:

Alembic\BioBundle\Entity\Categorie Object
(
    [nom:Alembic\BioBundle\Entity\Categorie:private] => PAINS
    [id:Alembic\BioBundle\Entity\Categorie:private] => 1
)

PAINS 的 id 不应为 1...

如果我尝试,我也会得到奇怪的输出:$repo->findXXX()

优先级:我想找到一种方法让我的 find()-based-methods 开始正常工作。数据库架构更新是次要问题...(如果这与 findXXX() 问题没有直接关系)。

【问题讨论】:

  • 正如我在您的转储 sql 语句中看到的,您将 categorie id 类型设置为 tinyint(1) 并且您的所有问题都是由它引起的(tinyint(1) 的值仅为 0、1) .要解决所有问题,请将 id 类型定义更改为 int。
  • @kibao,仅供参考 tinyint 可以存储 -128 到 +127 或 0 到 255(无符号)
  • findAll() 返回一个数组。很明显,您没有正确地迭代数组。
  • @Cerad:我不是在遍历数组,而是在整个结果上使用 print_r。第二个例子清楚地表明存在问题。我使用 Doctrine 至少一年了,这是我第一次看到。
  • @b.b3rn4rd 我同意tinyint,但tinyint(1) 只显示0,1。 stackoverflow.com/a/4401696/1851887.

标签: mysql symfony doctrine-orm


【解决方案1】:

前奏

修复映射元数据应该是您的最高优先级。当映射元数据不正确或与数据库不同步时,可能会发生各种奇怪的事情。

我怀疑您描述的大多数问题都来自于学说使用了不正确的标识符属性定义。

修复映射元数据

命令doctrine:mapping:import 将尝试基于现有数据库创建映射元数据。这个过程是猜测,很可能不会产生 100% 正确的映射元数据。

手动检查映射元数据并更正需要更正的内容非常重要。请这样做。

我怀疑标识符属性(数据库中的id 列)是使用“Doctrine 映射类型”boolean 映射的。这就是doctrine:schema:update 命令尝试将列类型更改为TINYINT(1) 的原因之一。您可能想在此处使用类型 integer

您可以使用命令doctrine:schema:validate检查映射元数据是否正确并与数据库同步。

您也可能遇到不容易解决的情况。并非所有数据库供应商的所有构造都被 Doctrine 开箱即用地支持。在许多情况下,它可以解决,但请针对该特定情况提出一个新问题。

一点建议

请不要使用改变映射元数据的命令/生成器,也不要使用实体。

在没有映射元数据的情况下(在项目开始时)生成映射元数据很好,但我的经验表明,重复执行以更改映射元数据(尤其是实体)会产生比它解决的问题更多的问题。

恕我直言,您应该从您的代码向您的数据库工作(而不是相反)。

【讨论】:

  • 非常感谢!您对导入是正确的,例如,我在两个实体之间有双向关系,但在原始表中带有一个参数。但是 Doctrine 在导入过程中失去了这个领域。所以我不得不手动创建一个中间实体并改变三个实体之间的关系。我放弃了我的表格,并从 Doctrine 创建了表格。您在“布尔 ID”上也是 100% 正确的,这导致了很多问题。现在工作得很好。感谢您的回答。喜欢我吧!
猜你喜欢
  • 1970-01-01
  • 2013-08-03
  • 2020-09-20
  • 2012-07-16
  • 2017-07-21
  • 2023-04-08
  • 2018-05-22
  • 2021-12-27
  • 1970-01-01
相关资源
最近更新 更多