Package git repository
https://github.com/phalcon/migrations
Requirements
- PHP >= 8.2
- The PDO extension and the PDO driver for your database:
pdo_mysql,pdo_pgsqlorpdo_sqlite - The
yamlextension, only if you use a YAML configuration file - The
posixextension (optional, Linux and macOS). Without it, the output has no colors.
Supported databases
| Database | adapter value |
Notes |
|---|---|---|
| MySQL | mysql |
Default port: 3306. The connection always uses the utf8 charset. |
| PostgreSQL | postgresql |
Default port: 5432. Default schema: public. |
| SQLite | sqlite |
The dbname value is the path to the database file. |
The adapter value is not case-sensitive.
Installing via Composer
composer require --dev phalcon/migrationsUsing the PHAR
Each release on GitHub has a phalcon-migrations.phar file. Download it from the releases page. Run it with PHP:
php phalcon-migrations.phar listThe PHAR accepts the same arguments and options as vendor/bin/phalcon-migrations.
Quick start
What you need for a quick start:
- Configuration file in the root of your project (you can also pass them as parameters inside CLI environment)
- Create database table structure
- Execute command to generate migrations
After that, you can execute that migration (run) in another environment to create the same DB structure.
Create the configuration file
The configuration file is a PHP file that returns an array. You can use any file name, for example migrations.php.
<?php
return [
'database' => [
'adapter' => 'mysql',
'host' => '127.0.0.1',
'port' => 3306,
'username' => 'root',
'password' => '',
'dbname' => 'db-name',
],
'application' => [
'logInDb' => true,
'migrationsDir' => 'db/migrations',
// true - TIMESTAMP, false - versions
'migrationsTsBased' => true,
'exportDataFromTables' => [
// Tables names
],
],
];For all the configuration keys, see Configuration.
Generate migrations
Basic generation
vendor/bin/phalcon-migrations generateGenerate a specific table and export data from it
vendor/bin/phalcon-migrations generate \
--config=migrations.php \
--table=users \
--data=oncreateThe --table option accepts:
- One table name:
--table=users - A comma-separated list of table names:
--table=users,roles - A table prefix with an asterisk:
--table=user*
For the data options, see Export data.
Run migrations
vendor/bin/phalcon-migrations runRoll back migrations
To roll back, use run with --version. Set --version to a version that is earlier than the current version:
vendor/bin/phalcon-migrations run --version=1.0.1The package goes back one version at a time. For each table, it calls the down() and afterDown() methods of the version that it removes. Then it calls the morph() method of the previous version. See Migration methods.
List existing migrations
vendor/bin/phalcon-migrations listThe command shows each version and if it was applied:
┌───────────────────────────┬──────────────┐
│ Version │ Was applied │
├───────────────────────────┼──────────────┤
│ 1.0.0 │ Y │
│ 1.0.1 │ N │
└───────────────────────────┴──────────────┘Configuration
The configuration has two sections: database and application.
Database options
| Key | Description |
|---|---|
adapter |
Database adapter: mysql, postgresql or sqlite |
host |
Database server host (MySQL and PostgreSQL) |
port |
Database server port. Default: 3306 (MySQL), 5432 (PostgreSQL) |
username |
Database user name |
password |
Database password |
dbname |
Database name. For SQLite, the path to the database file |
schema |
Schema that the package reads and changes. Default: the dbname value (MySQL), public (PostgreSQL). For PostgreSQL, the package also sets search_path to this schema |
Application options
| Key | Description |
|---|---|
migrationsDir |
Migrations directory. To use more than one directory, separate them with commas |
logInDb |
true - keep the migrations log in the database. false (default) - keep it in a file. See Migrations log |
migrationsTsBased |
true - run and list use timestamp based versions. false (default) - incremental versions |
descr |
Description for timestamp based versions. When you set it, generate always creates a timestamp based version |
exportDataFromTables |
Tables to export data from. An array, or a comma-separated string. The data is exported with every migration |
no-auto-increment |
true - same as the --no-auto-increment option |
skip-ref-schema |
true - same as the --skip-ref-schema option |
skip-foreign-checks |
true - same as the --skip-foreign-checks option |
Other configuration formats
The package also reads .ini, .json, .yaml and .yml files. These files use the same database and application sections. A YAML file needs the yaml PHP extension.
[database]
adapter = mysql
host = 127.0.0.1
username = root
password =
dbname = db-name
[application]
logInDb = true
migrationsDir = db/migrations
migrationsTsBased = true
exportDataFromTables = users,rolesProject directory
The project directory is the value of the --directory option. The default is the current directory.
These paths are relative to the project directory:
- The
--configfile - A relative
--migrationsormigrationsDirdirectory
Configuration file discovery
If you do not use --config, the package looks for a configuration file in the project directory. It looks in app/config/ first, then in config/. In each directory, it looks for these files, in this order:
config.iniconfig.phpconfig.jsonconfig.yamlconfig.yml
The package uses the first file that it finds. If it finds no file, the command stops with an error.
Default migrations directory
If you do not set --migrations or migrationsDir, the package uses the first of these directories that applies:
app/migrations, if theappdirectory existsapps/migrations, if theappsdirectory existsmigrations
If you set more than one migrations directory, generate asks which directory to use.
Migrations log
The package records each version that it applies. It uses the log to find the versions to run, and to show the status in list.
- File (default). The log is the
.phalcon/migration-versionfile in the project directory. - Database. Set
logInDbtotrue, or use the--log-in-dboption. The log is thephalcon_migrationstable. If the table does not exist, the package creates it. The table has the columnsversion,start_timeandend_time.
Usage example
Run migrations from specific migrations directory
<?php
use Phalcon\Migrations\Migrations;
use Phalcon\Migrations\Utils\Config;
$config = Config::fromArray([
'database' => [
'adapter' => 'mysql',
'host' => 'phalcon-db-mysql',
'username' => 'root',
'password' => 'root',
'dbname' => 'vokuro',
],
]);
Migrations::run([
'directory' => __DIR__,
'migrationsDir' => [
__DIR__ . '/migrations',
],
'config' => $config,
]);The config value must be a Phalcon\Migrations\Utils\Config object. Use Config::fromArray() to create it from an array with the database and application sections. If you use a plain array, Migrations::run() throws an exception with the message Internal error. Config should be an instance of Phalcon\Migrations\Utils\Config.
Migrations::run() accepts these options:
| Key | Type | Description |
|---|---|---|
config |
Config |
Database configuration (required) |
migrationsDir |
array / string |
Migrations directories (required) |
directory |
string |
Project directory, which holds the file log. Default: the BASE_PATH constant, or the parent directory of APP_PATH. Set it if you do not define these constants |
version |
string |
Version to migrate to. Default: the latest version |
tableName |
string |
Table name, comma-separated table names or a prefix with an asterisk. Default: @ (all tables) |
tsBased |
bool |
true - use timestamp based versions |
migrationsInDb |
bool |
true - keep the migrations log in the phalcon_migrations table |
verbose |
bool |
true - show debugging information |
skip-foreign-checks |
bool |
true - disable the foreign key checks during the run |
Migration files
Each version is a directory in the migrations directory. The version directory has one PHP file for each table. Each file has one class, which extends Phalcon\Migrations\Mvc\Model\Migration.
The class name is the table name in CamelCase, then Migration_, then the version stamp:
- For an incremental version
X.Y.Z, the stamp isX * 100 + Y * 10 + Z. - For a timestamp based version, the stamp is the timestamp part of the name.
For example, the class for the users table in version 1.0.0 is UsersMigration_100.
A generated file is similar to this (shortened) example:
<?php
use Phalcon\Migrations\Db\Column;
use Phalcon\Migrations\Db\Index;
use Phalcon\Migrations\Db\Reference;
use Phalcon\Migrations\Mvc\Model\Migration;
/**
* Class UsersMigration_100
*/
class UsersMigration_100 extends Migration
{
/**
* Define the table structure
*
* @return void
* @throws Exception
*/
public function morph(): void
{
$this->morphTable('users', [
'columns' => [
new Column(
'id',
[
'type' => Column::TYPE_INTEGER,
'unsigned' => true,
'notNull' => true,
'autoIncrement' => true,
'size' => 10,
'first' => true
]
),
new Column(
'email',
[
'type' => Column::TYPE_VARCHAR,
'notNull' => true,
'size' => 255,
'after' => 'id'
]
),
],
'indexes' => [
new Index('PRIMARY', ['id'], 'PRIMARY'),
],
]);
}
/**
* Run the migrations
*
* @return void
*/
public function up(): void
{
}
/**
* Reverse the migrations
*
* @return void
*/
public function down(): void
{
}
}Migration methods
Each migration is a separate class that works as an entity for a specific database table. Inside each class, different methods can occur during migration running.
Each migration file (and class) can implement specific methods, that will be executed based on the operation requested. There are no restrictions on the logic encapsulated in each method.
The tables below show the Migration Class methods. They are stored by order of execution, earliest to latest.
Running to up
| Method name | Description |
|---|---|
morph |
Morph table structure |
afterCreateTable |
Make something immediately after the table was created |
up |
Table is created and ready to work with |
afterUp |
Extra method to work for some specific cases |
Running to down
| Method name | Description |
|---|---|
down |
Normally you put here table drop or data truncation |
afterDown |
Extra method to work after all was cleaned up |
morph |
(from previous migration) As the migration was moved backward, there need to be all returned to the previous state |
Helper methods
The Phalcon\Migrations\Mvc\Model\Migration class has these methods, which you can use in your migration methods:
| Method | Description |
|---|---|
morphTable(string $tableName, array $definition): void |
Creates the table, or changes the table to match the columns, indexes, references and options in the definition |
batchInsert(string $tableName, array $fields, int $size = 1024): void |
Inserts the rows of the <table>.dat file of the version. It inserts $size rows in each query |
batchDelete(string $tableName): void |
Deletes all the rows of the table, if the <table>.dat file of the version exists |
getConnection(): AdapterInterface |
Returns the database adapter (Phalcon\Migrations\Db\Adapter\AdapterInterface) |
Export data
generate can export the data of a table. It writes the rows to a <table>.dat file (CSV format) in the version directory. The --data option controls how the migration imports the data:
| Value | Generated code |
|---|---|
oncreate |
afterCreateTable() calls batchInsert(). The data is imported only when the table is created |
always |
up() calls batchInsert() and down() calls batchDelete(). The data is imported on each run |
The tables in exportDataFromTables (or --exportDataFromTables) get the same code as always.
CLI Arguments and options
Arguments
| Argument | Description |
|---|---|
generate |
Generate a Migration |
run |
Run a Migration |
list |
List all available migrations |
migrate-files |
Update migration files to use the Phalcon\Migrations\Db classes. See Upgrade from 3.x to 4.0 |
help |
Shows the help |
Options
| Action | Description |
|---|---|
--config=s |
Configuration file, relative to the project directory |
--migrations=s |
Migrations directory. Use comma separated string to specify multiple directories |
--directory=s |
Directory where the project was created |
--table=s |
Table to migrate. Table name, comma-separated table names, or table prefix with an asterisk. Default: all |
--version=s |
Version to generate, or version to migrate to |
--descr=s |
Migration description (used for timestamp-based migration) |
--data=s |
Export data [‘always’ or ‘oncreate’] (Data is imported during migration run) |
--exportDataFromTables=s |
Export data from specific tables, use comma-separated string |
--force |
Forces to overwrite existing migrations |
--ts-based |
Timestamp based migration version |
--log-in-db |
Keep migrations log in the database table rather than in file |
--dry |
Attempt requested operation without making changes to system (Generating only) |
--dry-run |
Show the files to change, but do not change them (migrate-files only) |
--verbose |
Output of debugging information during operation (Running only) |
--no-auto-increment |
Disable auto-increment (Generating only) |
--skip-ref-schema |
Skip referencedSchema inside generated migration (Generating only) |
--skip-foreign-checks |
Disable the foreign key checks during the run. MySQL: SET FOREIGN_KEY_CHECKS. PostgreSQL: SET session_replication_role (Running only) |
--help |
Shows this help |
Incremental versions
By default, generate creates incremental versions. The first version is 1.0.0. Each new version adds one to the last number: 1.0.1, 1.0.2 and so on.
To set the version name, use --version:
vendor/bin/phalcon-migrations generate --version=2.0.0If the version already exists, the command stops with an error. To overwrite the files of the existing version, add --force.
Timestamp based migrations
Using this approach is useful when more than one developer is participating in the database structure management.
- To generate a timestamp based version, set a description with the
--descroption, or withdescrin the config file. - To run or list timestamp based versions, use
'migrationsTsBased' => truein the config file, or the--ts-basedoption.
The description can contain only lowercase letters, digits and underscores (_). If it has other characters, the command stops with an error. For example:
vendor/bin/phalcon-migrations generate --descr=create_usersThe command creates a version directory with a name like this:
* 1582539287636860_create_usersThe name is the current Unix time in microseconds, then _, then the description.
Migrations will be executed from oldest to newest.
Upgrade from 3.x to 4.0
Version 4.0.0 removes the dependency on the Phalcon extension. To upgrade:
- Use PHP 8.2 or later.
- Change your PHP configuration file to return an array. See Create the configuration file.
- If you call
Migrations::run()in your code, useConfig::fromArray()for theconfigoption. See Usage example. - Update your migration files with the
migrate-filescommand.
First, see the files that the command changes:
vendor/bin/phalcon-migrations migrate-files --migrations=db/migrations --dry-runThen change the files:
vendor/bin/phalcon-migrations migrate-files --migrations=db/migrationsThe --migrations option is required. The path is relative to the current directory. The command reads all the .php files in the directory and its subdirectories, and replaces these lines:
| Old line | New line |
|---|---|
use Phalcon\Db\Column; |
use Phalcon\Migrations\Db\Column; |
use Phalcon\Db\Index; |
use Phalcon\Migrations\Db\Index; |
use Phalcon\Db\Reference; |
use Phalcon\Migrations\Db\Reference; |
Migration files that you do not update continue to work if the Phalcon\Db classes are available, for example from the Phalcon extension. The package converts the Phalcon\Db\Column, Phalcon\Db\Index and Phalcon\Db\Reference objects when the migration runs.