Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQLite adapter drops table on changeColumn if there's a foreign key #922

Closed
bkanber opened this issue Jul 26, 2016 · 8 comments
Closed

SQLite adapter drops table on changeColumn if there's a foreign key #922

bkanber opened this issue Jul 26, 2016 · 8 comments
Assignees
Labels

Comments

@bkanber
Copy link

bkanber commented Jul 26, 2016

I get the following error when running a changeColumn command with the SQLite adapter: Cannot update a table that doesn't exist!

After digging in, I've found that the error only occurs if the table has a foreign key, but that it occurs consistently with a FK.

Test case:

    public function up()
    {

        $table = $this->table('broken_index');
        $table->addColumn('user_id', 'integer');
        $table->addColumn('created_at', 'datetime');
        $table->addColumn('changeme', 'string', ['null' => true]);
        $table->create();


        // Comment this out and the migration is OK
        // Leaving it in causes the table to be dropped :(

        $table->addForeignKey('user_id', 'users', 'id', ['delete' => 'CASCADE', 'update' => 'CASCADE']);

        // Regular indices are OK
        $table->addIndex('user_id');
        $table->addIndex('created_at');
        $table->update();

        var_dump($table->exists()); // true in all cases

        $table->changeColumn('changeme', 'text', ['null' => true]);

        var_dump($table->exists()); // FALSE if addForeignKey, TRUE if not

        // This command fails.
        $table->update();

    }
@rquadling
Copy link
Collaborator

Can you run the migration with -vvv?

@bkanber
Copy link
Author

bkanber commented Jul 26, 2016

 == 20160726203345 TestMigration: migrating
bool(true)
bool(false)


  [RuntimeException]                         
  Cannot update a table that doesn't exist!  


Exception trace:
 () at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/src/Phinx/Db/Table.php:617
 Phinx\Db\Table->update() at /Users/bkanber/PhpstormProjects/Components/migrations/spam/20160726203345_test_migration.php:55
 TestMigration->up() at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/src/Phinx/Migration/Manager/Environment.php:117
 Phinx\Migration\Manager\Environment->executeMigration() at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php:284
 Phinx\Migration\Manager->executeMigration() at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/src/Phinx/Migration/Manager.php:260
 Phinx\Migration\Manager->migrate() at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/src/Phinx/Console/Command/Migrate.php:113
 Phinx\Console\Command\Migrate->execute() at /Users/bkanber/PhpstormProjects/Components/vendor/symfony/console/Command/Command.php:256
 Symfony\Component\Console\Command\Command->run() at /Users/bkanber/PhpstormProjects/Components/vendor/symfony/console/Application.php:841
 Symfony\Component\Console\Application->doRunCommand() at /Users/bkanber/PhpstormProjects/Components/vendor/symfony/console/Application.php:189
 Symfony\Component\Console\Application->doRun() at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/src/Phinx/Console/PhinxApplication.php:82
 Phinx\Console\PhinxApplication->doRun() at /Users/bkanber/PhpstormProjects/Components/vendor/symfony/console/Application.php:120
 Symfony\Component\Console\Application->run() at /Users/bkanber/PhpstormProjects/Components/vendor/robmorgan/phinx/bin/phinx:28

migrate [-c|--configuration CONFIGURATION] [-p|--parser PARSER] [-e|--environment ENVIRONMENT] [-t|--target TARGET] [-d|--date DATE]

The exception itself is thrown when $table->update() checks if (!$this-exists()).

Looks like SqliteAdapter::changeColumn does some table juggling: it renames the table to tmp_tablename, creates a new table using the old table definition plus the new column, copies the data from the temp table to the new one, and then drops the temp table. Not sure where it's going wrong because it's tough to follow but my guess is that the preg_replace transformation on the table definition SQL breaks if there's a foreign key statement in there. The new table is never created, the data is never copied, but the temp table is dropped, leaving us with neither new table nor temp table. Dunno why the failed table creation doesn't throw an exception.

@rquadling
Copy link
Collaborator

Thanks for that analysis.

Definitely the regex. It is removing a ',' and that causes the foreign key clause to become part of the column.

Just need to make sure all tests still pass and any other instances of this issue.

@rquadling rquadling added the bug label Jul 27, 2016
@rquadling rquadling self-assigned this Jul 27, 2016
@bkanber
Copy link
Author

bkanber commented Jul 31, 2016

Awesome, thank you! Does phinx have a donation page?

@rquadling
Copy link
Collaborator

I don't think so. But instead of a donation to us, maybe a donation to a https://www.codeclubworld.org/

@robmorgan
Copy link
Member

Hi @bkanber you can contribute to the Phinx project at the bottom of https://phinx.org/

Cheers!

Rob

@rquadling
Copy link
Collaborator

@robmorgan Ha! Didn't see that.

@robmorgan
Copy link
Member

@rquadling ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants