Using
migrations & fixtures
Miro Svrtan
@msvrtan
Migrations
Server migrations
Database system migrations
Schema migrations
Schema migrations
Model schema
Database schema
Create migration
Calculate differences
Create migration file
Model schema
Database schema
Source of truth!
Calculate differences
Create migration file
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
class Version2 extends AbstractMigration
{
public function up(Schema $schema)
{
$this->addSql('CREATE TABLE user (id INT NOT NULL, username VARCHAR(180), ...)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_957A6479C05FB297 ON user (username)');
}
...
}
Version2
Version1
Run migration
Any new migrations?
Run migration `Version2`
Version1
Mark migration `Version2` as run
Version2
Version2
Run migration (again)
Any new migrations?
Nope, I'm done
Version1
Version1
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
class Version2 extends AbstractMigration
{
public function up(Schema $schema)
{
$this->addSql('CREATE TABLE user (id INT NOT NULL, username VARCHAR(180), ...)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_957A6479C05FB297 ON user (username)');
}
public function down(Schema $schema)
{
$this->addSql('DROP TABLE user');
}
}
Move forward/ no rollbacks
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
class Version20181027165500 extends AbstractMigration
{
public function up(Schema $schema)
{
...
}
public function down(Schema $schema)
{
..
}
}
Versioning
<?php
namespace DoctrineMigrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
class Version20181027165500 extends AbstractMigration
{
public function up(Schema $schema)
{
$this->abortIf('postgresql' !== $this->getDatabasePlatform(),
'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE TABLE user (id INT NOT NULL, username VARCHAR(180), ...)');
$this->addSql('CREATE UNIQUE INDEX UNIQ_957A6479C05FB297 ON user (username)');
}
public function down(Schema $schema)
{
$this->abortIf('postgresql' !== $this->getDatabasePlatform(),
'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('DROP TABLE user');
}
}
Locked to vendor
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUserTable extends Migration
{
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
...
});
}
public function down()
{
Schema::drop('users');
}
}
Laravel migrations
Deployment
Deploying on large datasets
Fixtures
'dummy' instead of production data
Fixtures
<?php
namespace App\DataFixtures\ORM;
use App\Entity\User;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
class UsersFixtures extends AbstractFixture
{
public function load(ObjectManager $manager)
{
$user1 = new User();
$user1->setId(1);
$user1->setUsername('username1');
$user1->setEmail('username1@example.com');
$user2 = new User();
$user2->setId(2);
$user2->setUsername('username2');
$user2->setEmail('username2@example.com');
$manager->persist($user1);
$manager->persist($user2);
$manager->flush();
}
}
<?php
namespace App\DataFixtures\ORM;
use App\Entity\User;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
class UsersFixtures extends AbstractFixture
{
public function load(ObjectManager $manager)
{
for ($i = 1; $i < 10; $i++) {
$user = new User();
$user->setId($i);
$user->setUsername('username'.$i);
$user->setEmail('username'.$i.'@example.com');
$manager->persist($user);
}
$manager->flush();
}
}
<?php
namespace App\DataFixtures\ORM;
use App\Entity\User;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\Persistence\ObjectManager;
class UsersFixtures extends AbstractFixture
{
public function load(ObjectManager $manager)
{
for ($i = 1; $i < 10; $i++) {
$user = new User();
$user->setId($i);
$user->setUsername('username'.$i);
$user->setEmail('username'.$i.'@example.com');
$manager->persist($user);
}
$manager->flush();
}
}
<?php
namespace App\DataFixtures\ORM;
..
class UsersFixtures extends AbstractFixture
{
public function load(ObjectManager $manager)
{
$alex = new User();
$alex->setId(1);
$alex->setUsername('alex');
$alex->setEmail('alex@example.com');
$sasha = new User();
$sasha->setId(2);
$sasha->setUsername('sasha');
$sasha->setEmail('sasha@example.com');
$manager->persist($alex);
$manager->persist($sasha);
$manager->flush();
}
}
Proper naming!
Demo time
Thank you!
Miro Svrtan
@msvrtan
Feedback -> https://joind.in/talk/6c119
miro (at) mirosvrtan.me
Any questions?
Using migrations and fixtures
By Miro Svrtan
Using migrations and fixtures
- 2,430