This course is still being released! Check back later for more chapters.
Migrations
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeWe 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!
// ... 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'
.
// ... 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!