Development

#7272 (doctrine:generate-migrations-diff fails when using inheritance)

You must first sign up to be able to contribute.

Ticket #7272 (closed defect: fixed)

Opened 4 years ago

Last modified 1 year ago

doctrine:generate-migrations-diff fails when using inheritance

Reported by: Renaud Assigned to: Jonathan.Wage
Priority: major Milestone:
Component: sfDoctrinePlugin Version: 1.4.1
Keywords: doctrine inheritance migration Cc: jean-gui, develop7, pulse00
Qualification: Unreviewed

Description

For this schema:

TestTable:
  columns:
    name:   { type: string }

TestTable2:
  inheritance:  { extends: TestTable, type: simple }
  columns:
    value:  { type: string(40) }

TestTable3:
  inheritance:  { extends: TestTable2, type: simple }
  columns:
    flag:   { type: boolean }

Fatal error when generate migration diff:

$ ./symfony doctrine:generate-migrations-diff
Fatal error: Class 'ToPrfxTestTable2' not found in /tmp/toprfx_doctrine_tmp_dirs/ToPrfxTestTable3.php on line 14

Attachments

7272.tar.gz (5.3 MB) - added by futurecat on 10/21/09 14:37:54.
sf1.3 sandbox with failing schema
Patches.zip (2.8 kB) - added by pulse00 on 02/14/10 21:06:01.
Patch
sfDoctrineGenerateMigrationsDiffTask.class.php.patch (0.7 kB) - added by develop7 on 02/14/10 21:46:04.
0001-symfony-migrations-fix.patch (1.4 kB) - added by pulse00 on 02/15/10 21:37:50.
symfony patch
0002-doctrine-migrations-fix.patch (3.6 kB) - added by pulse00 on 02/15/10 21:42:15.
doctrine patch
0001-doctrine-fixes.patch (3.6 kB) - added by pulse00 on 02/15/10 22:28:28.
correct doctrine patch
0002-doctrine-fixes.patch (4.3 kB) - added by tommyd on 03/22/10 15:42:53.

Change History

10/20/09 20:26:36 changed by futurecat

The probleme comes from Doctrine. I created a ticket on Doctrine's Jira. http://www.doctrine-project.org/jira/browse/DC-126

10/21/09 14:08:58 changed by futurecat

After trying to reproduce the bug in a doctrine 1.2 sandbox & Symfony 1.3 sandbox, it appears that the bug only appears with symfony.

My guess is that there is an autoloading conflict somewhere...

I attach a symfony 1.3 sandbox wich will fail when running php symfony doctrine:generate-migrations-diff.

10/21/09 14:37:54 changed by futurecat

  • attachment 7272.tar.gz added.

sf1.3 sandbox with failing schema

10/27/09 16:25:43 changed by jukea

+1 here !

10/29/09 12:40:58 changed by futurecat

  • priority changed from minor to major.

I change the priority to Major because symfony 1.3 has a better way of handling inheritance. Being able to migrate is critical! Thanx

11/12/09 07:50:50 changed by Mark.Quezada

I'm also seeing this behavior with a single level of inheritance.

11/30/09 22:48:54 changed by Jonathan.Wage

  • status changed from new to closed.
  • resolution set to invalid.

Will work on this issue from Doctrine Jira.

12/02/09 21:12:12 changed by agilbert

The Jira ticket is closed as well... what is the definitive source for activity on this issue? I'm having the problem also:

>> doctrine  generating migration diff
>> file+     /private/var/folders/uO/uOcfxzTRGA8G6XQvExbGF++++TI/-Tmp-/doctrine_schema_87129.yml

Fatal error: Class 'ToPrfxpkContextCMSSlot' not found in /private/var/folders/uO/uOcfxzTRGA8G6XQvExbGF++++TI/-Tmp-/toprfx_doctrine_tmp_dirs/ToPrfxpkContextCMSButtonSlot.php on line 14

Thanks.

12/06/09 14:50:09 changed by Renaud

Excuse me but i don't understand why this ticket was closed.

12/06/09 19:26:47 changed by Kris.Wallsmith

I see DC-327 and DC-126. Both are marked as resolved (invalid & cannot reproduce).

12/28/09 21:43:32 changed by ornicar2

  • keywords set to doctrine inheritance migration.
  • status changed from closed to reopened.
  • version changed from 1.3.x DEV to 1.4.1.
  • resolution deleted.
  • summary changed from Problem with doctrine:generate-migrations-diff task when model use 2 level inheritance to doctrine:generate-migrations-diff fails when using inheritance.

I have the same problem. This is critical. Here is how to reproduce it:

1. Download the symfony 1.4.1 sandbox: http://www.symfony-project.org/get/sf_sandbox_1_4.tgz

2. Use the schema.yml shown in the symfony table inheritance documentation: http://www.symfony-project.org/advent_calendar/14/en

3. Build the project running "php symfony doctrine:build --all"

4. Run "php symfony doctrine:generate-migrations-diff"

It fails. You get "Fatal error: Class 'ToPrfxPerson?' not found in /tmp/toprfx_doctrine_tmp_dirs/ToPrfxStudent.php on line 14"

I reopen the bug here because in Doctrine Jira, some say this works fine with Doctrine without symfony: http://www.doctrine-project.org/jira/browse/DC-126

12/28/09 23:37:00 changed by jeremy

nthing that this is a real bug

01/06/10 01:04:14 changed by MisterF

It seems to be the autoloading problem mentioned by futurecat. All the registered autolaoders seems to ignore the temporary directory. I added the last two lines of the following snippet as a workarround in:

symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Migration/Diff.php

      protected function _generateModels($prefix, $item)
      {
          $path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . strtolower($prefix) . '_doctrine_tmp_dirs';
          set_include_path( get_include_path() . PATH_SEPARATOR . $path);
          spl_autoload_register( 'spl_autoload');

(follow-ups: ↓ 17 ↓ 19 ) 01/07/10 16:35:06 changed by jean-gui

Another workaround, perhaps less intrusive than the one proposed by MisterF would be to create/edit config/autoload.yml with the following content:

autoload:
  tmp:
    name:      tmp
    path:      /tmp
    recursive: true

Once the migration is done, I believe it's safer and better to comment these lines out, though.

01/07/10 16:53:33 changed by jean-gui

  • cc set to jean-gui.

01/24/10 04:21:11 changed by weaverryan

I've hit this same issue - exactly as described above. I have one model that extends another via column_aggregation. Both models ARE generated correctly in the tmp directory, but the child model class is loaded first.

The autoload.yml solution works very nicely - thanks jean-gui.

02/02/10 12:10:48 changed by ollietb

I've had the same problem but the solutions mentioned here work on my more simple sites but don't seem to work with larger, more complicated projects. I've spent a lot of time in the debugger trying to work out what the problem is, but I've only managed to find out that there are some models generated after the autoload is re-initialised. Sorry I can't be more specific, but hopefully this information can help in some way.

(in reply to: ↑ 13 ; follow-up: ↓ 18 ) 02/02/10 12:13:39 changed by ollietb

It's probably safer to only autoload the /tmp/fromprfx_doctrine_tmp_dirs/ and /tmp/toprfx_doctrine_tmp_dirs/, especially on a shared server

Replying to jean-gui:

Another workaround, perhaps less intrusive than the one proposed by MisterF would be to create/edit config/autoload.yml with the following content: {{{ autoload: tmp: name: tmp path: /tmp recursive: true }}} Once the migration is done, I believe it's safer and better to comment these lines out, though.

(in reply to: ↑ 17 ) 02/05/10 15:06:16 changed by develop7

  • cc changed from jean-gui to jean-gui, develop7.

Replying to ollietb:

It's probably safer to only autoload the /tmp/fromprfx_doctrine_tmp_dirs/ and /tmp/toprfx_doctrine_tmp_dirs/, especially on a shared server

Well, in my case temporary model files are stored in /tmp/<random_4digit_number>/fromprfx_doctrine_tmp_dirs/. So adding whole /tmp dir into autoload.yml caused lots of warnings, because some directories in my /tmp were not accessible for current user.

BTW, these temporary directories are not cleaned after migration, so adding them all to autoload looks very bad idea to me.

(in reply to: ↑ 13 ; follow-up: ↓ 20 ) 02/10/10 13:42:16 changed by develop7

Good news, everyone!

the following snippet looks the best solution:

autoload:
  tmp:
    name:      tmp
    path:      /tmp/<?php echo getmypid()?>/toprfx_doctrine_tmp_dirs
    recursive: true

It autoloads only classes generated by current migration process. And, of course, no warnings, no fatal errors — everything goes clean.

Environment: Ubuntu 9.10, php 5.2.10, symfony 1.4 in PEAR.

Replying to jean-gui:

Another workaround, perhaps less intrusive than the one proposed by MisterF would be to create/edit config/autoload.yml with the following content: {{{ autoload: tmp: name: tmp path: /tmp recursive: true }}} Once the migration is done, I believe it's safer and better to comment these lines out, though.

(in reply to: ↑ 19 ) 02/10/10 14:57:37 changed by tommyd

Replying to develop7:

Good news, everyone! the following snippet looks the best solution: {{{ #!yml autoload: tmp: name: tmp path: /tmp/<?php echo getmypid()?>/toprfx_doctrine_tmp_dirs recursive: true }}}

Actually, this is not the best solution, because the autoload cache is kept after the migration command and even any in-between triggered symfony task will re-generate it and insert its own, bogus PID. The workaround for _this_ is to remove

$ rm -f cache/<appname>/<env>/config/config_autoload.yml.php

02/13/10 15:55:22 changed by pulse00

none of the above workarounds seem to work on OSX (10.6.1).

The tmp files under osx are generated in this folder:

/private/var/folders/8X/8XcjGvwEGKeUcmwvDdzkS++++TI/-Tmp-

so i created a config/autoload.yml like this:

autoload:
  tmp:
    name:      tmp
    path:      /private/var/folders/8X/8XcjGvwEGKeUcmwvDdzkS++++TI/-Tmp-/<?php echo getmypid()?>/toprfx_doctrine_tmp_dirs
    recursive: true

cleared the cache, but get the same error when running the migrations diff task.

Anyone tried this workaround on osx?

02/14/10 21:06:01 changed by pulse00

  • attachment Patches.zip added.

Patch

(follow-up: ↓ 23 ) 02/14/10 21:12:28 changed by pulse00

i've attached 3 patches which fix the issue.

Doctrine_Core.php:

* added member variable migration_tmp_path with getter and setter

* if migration_tmp_path is set in the static autoload callback, check there too for classes

Doctrine_Migration_Diff.php:

* added getters for _fromPrefix and _toPrefix

sfDoctrineGenerateMigrationsDiffTask.class.php:

setting Doctrine_Core::setMigrationTmpPath(sys_get_temp_dir() . DIRECTORY_SEPARATOR . getmypid()) before executing the task, so the classes can be loaded

Not sure if there are any performance penalties because i altered the autoloading code, but as it's only done when _migration_path is set, it should be fine i think.

i'd be glad for feedback / suggestions about the patch.

02/14/10 21:46:04 changed by develop7

  • attachment sfDoctrineGenerateMigrationsDiffTask.class.php.patch added.

(in reply to: ↑ 22 ) 02/14/10 21:50:42 changed by develop7

pulse00, consider adding sfDoctrineGenerateMigrationsDiffTask.class.php.patch to your patchset. It clears temp files after generating migration and reloads autoload (to prevent bogus effect described in 20)

Replying to pulse00:

i've attached 3 patches which fix the issue. Doctrine_Core.php: * added member variable migration_tmp_path with getter and setter
* if migration_tmp_path is set in the static autoload callback, check there too for classes Doctrine_Migration_Diff.php: * added getters for _fromPrefix and _toPrefix sfDoctrineGenerateMigrationsDiffTask.class.php: setting Doctrine_Core::setMigrationTmpPath(sys_get_temp_dir() . DIRECTORY_SEPARATOR . getmypid()) before executing the task, so the classes can be loaded Not sure if there are any performance penalties because i altered the autoloading code, but as it's only done when _migration_path is set, it should be fine i think. i'd be glad for feedback / suggestions about the patch.

02/15/10 13:07:19 changed by develop7

  • cc changed from jean-gui, develop7 to jean-gui, develop7, pulse00.

02/15/10 21:37:50 changed by pulse00

  • attachment 0001-symfony-migrations-fix.patch added.

symfony patch

02/15/10 21:40:23 changed by pulse00

i've created 2 patches, one for symfony and one for doctrine. The symfony patch has the patch from develop7 included. Doctrine patch is attached to the corresponding doctrine ticket: http://www.doctrine-project.org/jira/browse/DC-126

02/15/10 21:42:15 changed by pulse00

  • attachment 0002-doctrine-migrations-fix.patch added.

doctrine patch

02/15/10 21:43:14 changed by pulse00

couldn't find a way to attach a file to the doctrine issue tracker, so i attached it here...

02/15/10 22:28:28 changed by pulse00

  • attachment 0001-doctrine-fixes.patch added.

correct doctrine patch

(follow-up: ↓ 28 ) 02/15/10 22:29:16 changed by pulse00

please disregard the first doctrine patch, it contained a typo. the last one is the correct one.

(in reply to: ↑ 27 ) 03/22/10 15:41:35 changed by tommyd

Replying to pulse00:

please disregard the first doctrine patch, it contained a typo. the last one is the correct one.

This patch doesn't work correctly on case-sensitive file systems - the migration class strtolower()'s the prefix when building the generated class path - this has been fixed. I also set a sane default for the $_migration_tmp_path member and let Doctrine_Migration_Diff use that as well instead of the plain sys_get_temp_dir() call.

03/22/10 15:42:53 changed by tommyd

  • attachment 0002-doctrine-fixes.patch added.

03/25/10 12:57:21 changed by weaverryan

With the disclaimer that I didn't look through the code, applying only the latest patch to doctrine by tommyd worked for me on a large project.

03/26/10 19:49:07 changed by Jonathan.Wage

While the patch works, we can't commit this. Could we possibly make another autoloader that migrations uses to load those classes? or can we just require all of them manually?

03/29/10 19:28:03 changed by Jonathan.Wage

  • status changed from reopened to closed.
  • resolution set to fixed.

(In [28871]) [1.3, 1.4] Fixing issue with migrations diff autoloading (fixes #7272)

03/29/10 19:28:46 changed by Jonathan.Wage

I think this last commit should help with the issue and fix it once and for all!

03/30/10 21:12:57 changed by weaverryan

This worked perfectly.

02/14/11 09:23:37 changed by neuromancer

I'm using symfony version 1.4.10-DEV and I still have this problem:

PHP Fatal error:  Class 'ToPrfxsfGuardUserProfile' not found in /tmp/3746/toprfx_doctrine_tmp_dirs/ToPrfxRappresentante.php on line 21

I'm unable to create migrations script with doctrine:generate-migrations-diff task.

My project use two connection on two different databases and I'm using also concrete inheritance between sfGuardUserProfile and two distinct user profiles that extend it.

Using solution proposed by jean-gui fix the problem for me. I just created autoload.yml in app/frontend/config directory with:

autoload:
  tmp:
    name:      tmp
    path:      /tmp
    recursive: true