This course is still being released! Check back later for more chapters.

Get Notified About this Course!

We will send you messages regarding this course only
and nothing else, we promise.
You can unsubscribe anytime by emailing us at:
privacy@symfonycasts.com
Login to bookmark this video
Buy Access to Course
04.

Migrations

|

Share this awesome video!

|

Keep on Learning!

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

We have a Starship entity... but no starship table! The solution? Database migrations!

make:migration

Create our first migration by running:

symfony console make:migration

Success! This didn't add the actual table, but it did create a new file in the migrations/ directory. Let's check it out!

Ooh, it's a PHP class where the up() method holds the SQL to create our table. What's neat is how this was created: Doctrine compared the current state of our entities to the database and generated the SQL needed to make them match. Wow!

34 lines | migrations/Version20241111171351.php
// ... lines 1 - 12
final class Version20241111171351 extends AbstractMigration
{
// ... lines 15 - 19
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE starship (id SERIAL NOT NULL, name VARCHAR(255) NOT NULL, class VARCHAR(255) NOT NULL, captain VARCHAR(255) NOT NULL, status VARCHAR(255) NOT NULL, arrived_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id))');
$this->addSql('COMMENT ON COLUMN starship.arrived_at IS \'(DC2Type:datetime_immutable)\'');
}
// ... lines 26 - 32
}

There's also a down() method... because migrations can be reversed, but I've never done that, so I don't worry about down().

One thing to note about the SQL: it's in the format of the database platform you're using. In our case, Postgres-specific SQL. If using SQLite, you'd see SQLite-specific SQL.

If you want, add a note about what this does in getDescription(): return 'Add starship table'.

34 lines | migrations/Version20241111171351.php
// ... lines 1 - 12
final class Version20241111171351 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add starship table';
}
// ... lines 19 - 32
}

Checking the Migration Status

Pop over to the terminal and run:

symfony console doctrine:migrations:list

The output is a bit wonky but we can see our migration class and its description. The status is not migrated because we haven't executed it yet. Let's do that!

symfony console doctrine:migrations:migrate

Are we sure we want to continue? Yes! Success! Try:

symfony console doctrine:migrations:list

again. Status: migrated!

How Migrations Work

But how does Doctrine track which migrations have been run? It creates a doctrine_migration_versions table, then inserts a row for each migration after it's executed.

We can see it! Run:

symfony console doctrine:query:sql 'select * from doctrine_migration_versions'

Look at that! There's our migration class, when it was executed, how long it took, and the migration's favorite color! Ok, not that last one.

Does this mean we have our starship table? Run another raw SQL query to find out!

symfony console doctrine:query:sql 'select * from starship'

The query yielded an empty result set.

Green means good, right? Yup! This tells us that there's no data in the starship table... but it does exist!

Entity class check: ✅ Database table check: ✅ Data in the database? Let's learn how to do that next!