Doctrine 尝试访问先前在迁移中删除的列

发布于 2024-12-04 05:53:43 字数 2586 浏览 7 评论 0原文

我通过将 Sample 模型和 Collector 模型之间的一对多关系转换为多对多关系,更改了 Symfony 应用程序的架构。 Sample 模型有一个 collector_id 外键,现在有一个带有两个外键的中间模型 (SampleCollectors):sample_id和<代码>collector_id。

Sample:
  columns:
    id:  { type: integer, primary: true, autoincrement: true }
    ...
    collector_id:  ... # This column is removed
    ...
  relations:
    ...
    Collectors:  { foreignAlias: Collectors, class: Collector, local: sample_id, foreign: collector_id, refClass: SampleCollectors }

Collector:
  columns:
    id:       { type: integer, primary: true, autoincrement: true }
    ...
  relations:
    Samples:  { foreignAlias: Samples, class: Sample, local: collector_id, foreign: sample_id, refClass: SampleCollectors }


SampleCollectors:
  columns:
    sample_id:    { type: integer, primary: true }
    collector_id: { type: integer, primary: true }
  relations:
    Sample:       { onDelete: cascade }

我已经像上面一样编辑了 schema.yml 文件并执行了以下任务:

  1. php symfony doc:generate-migrations-diff
  2. php symfony doc:build --all -classes

重建了每个涉及的模型/表单/过滤器并创建了两个迁移类。

由于数据库已经处于生产模式,我已经调整了迁移类以将一对多关系的外键 (Sample.collector_id) 移动到多对多中间表(SampleCollectors.collector_id):

public function preUp() {
  $sampleTable = Doctrine_Core::getTable('Sample');
  // I do this because collector_id has disappeared after model regeneration.
  $sampleTable->setColumn('collector_id', 'integer', null, array('type' => 'integer'));
  $this->samples = $sampleTable->findAll()->toArray();
}

public function up() {
  // ...
  $this->removeColumn('sample', 'collector_id');

  // ...
  $this->createTable('sample_collectors', array(...), array(
    'type' => 'INNODB',
    'primary' => array(0 => 'sample_id', 1 => 'collector_id'),
     ...));
}

public function postUp() {
  foreach ( $this->samples as $sample ) {
    $sampleCollector = new SampleCollectors();
    $sampleCollector->setSampleId($sample['id']);
    $sampleCollector->setCollectorId($sample['collector_id']);
    $sampleCollector->trySave();
  }
}

我已经迁移了数据库,一切都很顺利。

但现在我正在更新控制器、视图等,Doctrine 仍然尝试从 Sample 中检索 collector_id 列,而不是通过多对多关系进行导航。

既然 Sample 模型不再存储对它的引用,为什么 Doctrine 坚持这样做呢?我检查了 BaseSample 类,它没有设置列 collector_idhasColumn() 方法。顺便说一句,我也清除了缓存。

谢谢!

I have changed the schema of a Symfony application by transforming a one-to-many relationship to a many-to-many relationship between a Sample model and a Collector model. The Sample model had a collector_id foreign key and now there is an intermediate model (SampleCollectors) with two foreign keys: sample_id and collector_id.

Sample:
  columns:
    id:  { type: integer, primary: true, autoincrement: true }
    ...
    collector_id:  ... # This column is removed
    ...
  relations:
    ...
    Collectors:  { foreignAlias: Collectors, class: Collector, local: sample_id, foreign: collector_id, refClass: SampleCollectors }

Collector:
  columns:
    id:       { type: integer, primary: true, autoincrement: true }
    ...
  relations:
    Samples:  { foreignAlias: Samples, class: Sample, local: collector_id, foreign: sample_id, refClass: SampleCollectors }


SampleCollectors:
  columns:
    sample_id:    { type: integer, primary: true }
    collector_id: { type: integer, primary: true }
  relations:
    Sample:       { onDelete: cascade }

I have edited the schema.yml file like above and executed the following tasks:

  1. php symfony doc:generate-migrations-diff
  2. php symfony doc:build --all-classes

which has rebuilt every involved model/form/filter and created two migration classes.

Since the database is already in production-mode, I have tuned the migration classes to move the foreign key of the one-to-many relationship (Sample.collector_id) to the many-to-many intermediate table (SampleCollectors.collector_id):

public function preUp() {
  $sampleTable = Doctrine_Core::getTable('Sample');
  // I do this because collector_id has disappeared after model regeneration.
  $sampleTable->setColumn('collector_id', 'integer', null, array('type' => 'integer'));
  $this->samples = $sampleTable->findAll()->toArray();
}

public function up() {
  // ...
  $this->removeColumn('sample', 'collector_id');

  // ...
  $this->createTable('sample_collectors', array(...), array(
    'type' => 'INNODB',
    'primary' => array(0 => 'sample_id', 1 => 'collector_id'),
     ...));
}

public function postUp() {
  foreach ( $this->samples as $sample ) {
    $sampleCollector = new SampleCollectors();
    $sampleCollector->setSampleId($sample['id']);
    $sampleCollector->setCollectorId($sample['collector_id']);
    $sampleCollector->trySave();
  }
}

I have migrated the database and everything went apparently well.

But now that I'm updating the controllers, views, etc., Doctrine still tries to retrieve the collector_id column from Sample, instead of navigating through the many-to-many relationship.

Since the Sample model does not store a reference to it anymore, why does Doctrine insist on that? I checked the BaseSample class and it does not have a hasColumn() method setting a column collector_id. BTW, I clear the cache as well.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

分分钟 2024-12-11 05:53:43

我终于找到了问题所在。我已将 Doctrine 配置为在 ProjectConfiguration 类中使用 APC 缓存系统:

public function configureDoctrine(Doctrine_Manager $manager) {
  $manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, new Doctrine_Cache_Apc());
}

当您执行 php symfony cache:clear 时,此缓存不会被清除,因为它不是 Symfony 的东西,而是一个PHP 和 Web 服务器的事情。

您可以重新启动 Web 服务器或使用 apc_clear_cache(),如有关 APC 缓存的问题中所述一个>。

I finally found the problem. I had configured Doctrine to use the APC cache system in ProjectConfiguration class:

public function configureDoctrine(Doctrine_Manager $manager) {
  $manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, new Doctrine_Cache_Apc());
}

This cache is not cleared when you execute php symfony cache:clear, since is not a Symfony thing but a PHP and web server thing.

You can either restart the web server or use apc_clear_cache(), as noted in this question regarding APC cache.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文