We develop a framework which we include as a module in several projects. Both the framework and the projects contain phinx migrations.
Is there a way I can set up two (or more) migration paths in phinx.yml (one for framework migrations and one for project-specific migrations), so phinx looks in both paths for migrations? If not, it would be a great feature! The documentation talks about a "migration path" (singular) which implies that only one path can be specified.
It would be important that migrations are run in the sequence of the timestamps in the migration file names (as oposed to running all framework migrations and then project-specific migrations.
Here's an example of what I'd like to do, where migrations 1-4 are run in sequence:
phinx.yml (specify two paths, e.g. separated with semicolon)
paths:
migrations: %%PHINX_CONFIG_DIR%%/migrations;%%PHINX_CONFIG_DIR%%/vendor/our-company/our-framework/migrations
./migrations
20130101000000_migration_1.php
20130103000000_migration_3.php
./vendor/our-company/our-framework/migrations
20130102000000_migration_2.php
20130104000000_migration_4.php
+1
:+1:
Hi!
I'm here to learn Phinx. So, I'm programming an app with separated modules via composer. Every module has its own tables: when I install a module, I need to up that tables.
And I'm here :)
I opened the Phinx source, and It is really (really [REALLY]) like the "migration" proposed by Akrabat :)
http://akrabat.com/zend-framework/akrabat_db_schema_manager-zend-framework-database-migrations/
So, checking the code, I saw this line:
https://github.com/robmorgan/phinx/blob/0.3.x-dev/src/Phinx/Migration/Manager.php#L362
I think we can use glob expansions.
I'll try now =D
Aha! I found a solution!
Phinx searchs for migrations with glob. If we use glob expansions, we can do it. BUT, inside config getMigrationPath, a realpath is cleaning the expansions.
So, if we remove the realpath, Phinx will get all migrations ;)
paths:
migrations: ./modules/*/migrations
I didn't run the tests, but I think we can implement a resource that search for additional paths, like:
paths:
migrations: ./migrations
locationA: ./modules/*/migrations
locationB: ./vendors/*/migrations
@wandersonwhcr @aimfeld given the number of permutations migrations may have (ie multiple databases to multiple projects) you need to clarify further on how you want to manage your databases with one configuration across multiple migration directories
@BardiaAfshin In my case, I have only one project and only one database, so I can't comment on this, unfortunately. In my case I simply need to be able to specify multiple migration paths to look for migration files.
@aimfeld
You could write a wrapper command that will consume multiple configuration files, with each having a
different value for
migrations: %%PHINX_CONFIG_DIR%%
in phinx.yml file.
Since phinx is built upon symfony2/console component, this would be relatively a easy under taking
@BardiaAfshin
I'd have to look more deeply into symfony2/console. But I suspect that with a wrapper command, I could only run several phinx migrate command in sequence, with each iteration using one migration path. This would fail, because the migrations would be performed in the wrong sequence (in my example above: migration_1, migration_3, migration_2, migration_4) .
I agree with @wandersonwhcr that the Phinx\Migration\Manager::getMigrations() function would need to be changed to consume files from multiple migration paths. Using glob and wildcards will break other phinx commands though. Here's a backwards-compatible example of how the configuration could be extended:
paths:
migrations: %%PHINX_CONFIG_DIR%%/migrations
additional_migrations:
- %%PHINX_CONFIG_DIR%%/vendor/our-company/our-framework/migrations
- %%PHINX_CONFIG_DIR%%/vendor/other-company/other-framework/migrations
@robmorgan If my suggestion seems a good idea to the dev team, I can try to implement this and submit a pull request.
@robmorgan An alternative syntax would be the following (with the first path being the default migration path which is returned in the getMigrationPath() function:
paths:
migrations:
- %%PHINX_CONFIG_DIR%%/migrations
- %%PHINX_CONFIG_DIR%%/vendor/our-company/our-framework/migrations
- %%PHINX_CONFIG_DIR%%/vendor/other-company/other-framework/migrations
This could be made backwards compatible by checking if an array or a string is given for the migrations key.
Has this been solved in the meantime?
Also starring hard to this, any chance to get this @robmorgan ?
@robmorgan , what is the status of this feature?
Ping @robmorgan.
High demand. Any feedback for us whatsoever?
As I couldn't wait for this feature, I have implemented a workaround. I just copy all migration files from different paths into a single migrations directory during the deployment process. It's quite easy and works well for us.
I wrote a little helper. Script loads app config (Horus\Config) and creates a Phinx config each time it is called.
It's just my workaround but I am very happy. The creation of migrations is no pain anymore and it looks for migrations in all my bundle paths. Just take a look at the script...
#!/usr/bin/env php
<?php
$root = dirname(__DIR__);
require_once $root . '/vendor/autoload.php';
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Phinx\Console\PhinxApplication;
use Phinx\Config\Config as PConfig;
use Horus\Config;
$dispatcher = new EventDispatcher();
$dispatcher->addListener(ConsoleEvents::COMMAND, function (ConsoleCommandEvent $event) use ($root) {
$command = $event->getCommand();
if ($command instanceof Phinx\Console\Command\AbstractCommand) {
$input = $event->getInput();
$output = $event->getOutput();
$environment = 'development';
if ($input->hasOption('environment')) {
if (null !== $input->getOption('environment')) {
$environment = $input->getOption('environment');
} else {
$input->setOption('environment', $environment);
}
}
$config = Config::load($root . '/app/config/config_' . $environment . '.yml');
if (empty($config->toArray())) {
$output->writeln(sprintf('<error>Unknown environment "%s"</error>', $environment));
exit;
}
switch (get_class($command)) {
case 'Phinx\Console\Command\Create':
case 'Phinx\Console\Command\SeedCreate':
$migrations = 'Resources/migrations';
$seeds = 'Resources/migrations/seeds';
break;
default:
$migrations = $root . '/src/*/*/Resources/migrations';
$seeds = $root . '/src/*/*/Resources/migrations/seeds';
}
$config = new PConfig([
'environments' => [
'default_migration_table' => 'phinxlog',
'default_database' => $environment,
$environment => [
'adapter' => 'mysql',
'host' => $config->database->host,
'name' => $config->database->dbname,
'user' => $config->database->username,
'pass' => $config->database->password,
'port' => 3306,
'charset' => 'utf8'
]
],
'paths' => [
'migrations' => $migrations,
'seeds' => $seeds
],
]);
$command->setConfig($config);
}
});
$phinx = new Phinx\Console\PhinxApplication();
$phinx->setDispatcher($dispatcher);
$phinx->run();
Hi... It works!
Setup your variable paths.migrations like this:
{/path/to/my-project/db/migrations,/path/to/my-project/vendor/*/*/db/migrations}
Phinx loads all my migrations in db/migrations and in db/migrations in all my packages in vendor directory ;)
So, multiple directories with wildcard expansion in curly brackets, delimited by comma.
I hope, it helps :)
+1
@janreges this does not support creation of migration files
Yes the problem is the creating and to get the timestamp in the file name
馃憤
Look at this https://github.com/lulco/phoenix. Syntax is very similar to phinx but has this feature implemnted already.
fyi this is possible since 0.7.0 but Unfortunately it wasn't mentioned in the release notes.. ;)
https://github.com/robmorgan/phinx/blob/v0.7.0/tests/Phinx/Config/_files/valid_config.php
@rquadling @robmorgan maybe close this?
Confirmed. This feature was initially part of the 0.7 dev branch (https://github.com/robmorgan/phinx/pull/1022/commits/28d9afb01175704062277c5365f610a08fed21d4) It was merged as part of merging the dev branches into master.
Sorry for the lack of release notes.
Most helpful comment
Hi... It works!
Setup your variable
paths.migrationslike this:{/path/to/my-project/db/migrations,/path/to/my-project/vendor/*/*/db/migrations}Phinx loads all my migrations in db/migrations and in db/migrations in all my packages in vendor directory ;)
So, multiple directories with wildcard expansion in curly brackets, delimited by comma.
I hope, it helps :)