The Flow of Migrations
In this lesson, we'll learn about the various migration-based commands made available by the Ace CLI and how they interact with our migration files. We'll use these commands to run, rollback, and refresh our migrations against our database.
- Author
- Tom Gobich
- Published
- Feb 24, 24
- Duration
- 8m 28s

Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Transcript
The Flow of Migrations
-
(upbeat music)
-
So now we have all of our migrations
-
created within our project,
-
but we haven't actually done anything with them yet.
-
If we were to jump into PG admin at this point in time,
-
so right here, take a look at our Adonis 6 table.
-
We can jump down to the schemas underneath public.
-
If we scroll down a little bit more, we'll see tables.
-
If we expand that, we have nothing.
-
If we had something, for example,
-
if I jump up to the Atacast project,
-
jump down the schemas, go down the public tables,
-
it would look something a little bit like this,
-
where we have all of our tables listed out
-
using the names that we have defined within our migration.
-
So what we wanna do is actually run our migrations
-
so that those tables within our Adonis 6 database
-
actually get created and become populated
-
here inside of our database itself.
-
So let's hide PG admin back away
-
and let's jump into our terminal.
-
So we'll open that up and let's run node ace list once more
-
to see all of our commands.
-
Down here at the bottom,
-
we'd see a whole section dedicated to migrations.
-
We have migration fresh, refresh, reset,
-
rollback, run, and status.
-
Let's start with status so that we can actually see
-
what the current status is of our migrations.
-
So node ace migration status.
-
Okay, expanded this out a little bit
-
so that it doesn't text wrap.
-
We can see all of our migrations listed out
-
with the full path of that migration here.
-
Status is pending on all of them
-
because we haven't actually run them yet.
-
The batch number is going to be
-
the current batch that it ran in.
-
So if we were to run all of these,
-
all of them would have the same batch.
-
If we were to run just one of them,
-
one of them would be in batch one,
-
and then the others would be in a separate batch
-
if we were to run them later on.
-
So we can use this command to easily see
-
the current status of the migrations
-
that we have defined within our project.
-
If we scroll up a little bit more
-
to see the rest of the commands here,
-
we also have run, which as the helper text states,
-
is going to migrate the database
-
by running the pending migrations.
-
All of our migrations are in a pending status,
-
so this sounds like what we would want.
-
In essence, run is going to run the up command
-
for each of our migrations.
-
It's going to step through them in that natural sort order
-
that we defined using the timestamp
-
that's prefixed on each of the file names.
-
So it will run them in that order,
-
and it will run that up method inside of each of them.
-
So if we scroll back down here
-
and we run node ace migration run, hit enter on that,
-
it's going to migrate each of the files
-
in the exact order that we have them
-
sorted by the timestamp within the file name.
-
So if we were to run our status check again,
-
the status has changed to completed for all of them,
-
and all of them are in batch one.
-
If we were to add in our watch list and try to run again,
-
that watch list migration would be in batch two.
-
So if we scroll up to see our commands once more,
-
if we were to roll back,
-
by default that will roll back just one batch,
-
but you can also set it to a specific batch
-
that you want to roll back to.
-
So if you have 56 different batches,
-
you could roll back to batch 32 if you wanted to
-
by specifying that within this command.
-
And we can check out the help for that as well
-
by doing node ace migration rollback hyphen hyphen help.
-
You specify the batch with hyphen hyphen batch
-
equals that batch number.
-
So if we wanted to roll back to a specific batch,
-
we could do batch equals, and for example, 32, there it is.
-
But we don't have 32, we just have one.
-
So we won't actually run that right now.
-
Again, as I stated before, by default,
-
this command, if you run it without that batch specification,
-
we'll just run it back one batch.
-
Okay, we have a couple more commands.
-
We'll scroll up a little bit more.
-
And it's getting a little long to scroll up there.
-
We have reset, which will roll back all migrations.
-
So we'll run that here in a second
-
to see exactly what that does.
-
Then we have refresh.
-
We'll run that too here in a second.
-
And we have fresh here as well.
-
Refresh is a single command that will essentially run,
-
roll back, and then run.
-
And then fresh, fresh is useful if you're working
-
with a preexisting database that already has
-
different tables in it that you don't necessarily
-
need anymore.
-
So you wouldn't have migrations to actually roll them back,
-
but you could use fresh to just strip everything
-
out of that database and start from scratch
-
with the current migrations that you have in your project.
-
Okay, so let's roll back.
-
So scroll down, node, ace, migration, roll back,
-
and we'll see exactly what that does.
-
So you can see it reverted each of the migrations
-
that we have, and it's gonna do that in the inverse order
-
with which they were run whenever we were running up,
-
because now they're running down.
-
So in order for our users table to be deleted,
-
that role ID on the users table needs to be stripped out
-
before we can actually delete our roles table as a whole
-
due to the foreign key constraint that we have defined
-
between the relationship between those two
-
and other tables in our database.
-
So roll back is going to run based off the timestamp
-
in descending order.
-
And then whenever we run, it will run them
-
in ascending order.
-
Again, whenever we run migration run,
-
that's going to run the up method.
-
And then whenever we run roll back,
-
that will run the down method.
-
Okay, so let's go ahead and run our migrations again.
-
So node, ace, migration, run, and next we can run refresh.
-
So we'll take this back and we'll run refresh.
-
This will roll back our migrations and then re-migrate them.
-
So if we run this, there we go.
-
It reverted all of them and then re-migrated them.
-
This is really nice for development whenever you have,
-
say, an extra column to add into one of your tables,
-
you can add that in, run refresh to get that change
-
quickly picked up within your database.
-
Now at the current point in time,
-
there's going to be no difference between running roll back
-
and running reset because we only have one batch
-
within our migrations, but there is a difference.
-
So let's scroll up a little bit more
-
to where they're defined.
-
Reset will roll back all migrations,
-
regardless of the specific batch.
-
And then as we said before,
-
roll back will roll back to a specific batch
-
or by default when that's omitted,
-
just it will roll back one batch.
-
And then lastly, we have fresh,
-
which we can go ahead and run real quick.
-
That's just going to drop everything
-
without actually reverting anything.
-
It will just start us at a clean slate
-
and then run migration.
-
So node, ace, migration, fresh.
-
And there you go.
-
You see, it just dropped everything and then migrated.
-
It didn't actually revert anything.
-
It just straight up dropped it.
-
So those are the various migration commands
-
that Lucid provides to us that we can easily make use of
-
to roll back our migrations and run our migrations.
-
So roll back to go backwards and run to go forwards.
-
We'll take a look at our database here
-
to actually see our tables here in a second.
-
But before we do, I want to make an important note.
-
So once you have tables out in a production environment
-
for your application,
-
you will not want to roll them back
-
because rolling them back, reverting, resetting,
-
any of those commands are going to delete the data
-
that was in those tables.
-
And once you have information
-
out on your production environment,
-
you're not going to want to delete that information.
-
That's important information
-
that you want to persist long-term.
-
So if you have a change that you need to make
-
in your production environment, create a new migration,
-
make that change in that migration,
-
and then run that forward.
-
That particular flow
-
is what we're saving our watch lists for.
-
We're going to run through that later on in this series,
-
but I want to make that important distinction right now.
-
If it doesn't make sense to you at this point in time,
-
that's perfectly fine.
-
We'll run through it later on,
-
but just in case it does,
-
I want to make that important distinction right now,
-
just so you don't run into that situation yourself.
-
Okay, so let's jump back into pgAdmin here
-
and let's refresh our tables.
-
So I'm just going to right click on that
-
and click on refresh here within pgAdmin.
-
We now have a dropdown
-
and we now have a number of different tables
-
within our database.
-
This will list them out in alphabetical order.
-
So we have our cast movies, our cynists, our crew movies,
-
movie statuses, movies, roles, and users tables.
-
We also have our Adana schema
-
and our Adana schema version.
-
Within pgAdmin, we should be able to right click
-
on any one table,
-
go into the view or edit data section,
-
and we can select first 100 rows.
-
So this should print out the first 100 rows
-
within the database here for this particular table
-
and print it out right down here.
-
You'll notice that this looks fairly familiar
-
to the status command that we ran using the ACLI,
-
and that's because this is essentially what it's using
-
to determine whether or not a migration
-
has already run within our application
-
and additionally what batch number it ran in as well.
-
So whenever we run that status command
-
or whenever we run our migrations,
-
it's going to check in here
-
to see which migrations have already run
-
to determine which ones still need to run.
-
So this Adana schema table is vital to determining
-
and allowing us to run migrations within our application.
-
The Adana schema version is going to track
-
the particular migration version that we're working with.
-
That allows Adana's JS itself to make changes
-
without breaking older databases
-
that have been around for a while.
-
So it can do some progressive enhancement there.
-
And then we have all of our different tables,
-
which at this point in time are going to be empty.
-
So there's not much purpose
Join The Discussion! (2 Comments)
Please sign in or sign up for free to join in on the dicussion.
petzi
Hello everyone,
I recently had trouble connecting to my database because I used a password with special characters, specifically: Pa$$word. The special characters needed to be escaped, so I had to write it like this: Pa\$\$word (Note: I didn't try using the password inside strings.)
Just posting this in case someone else faces the same issue (because I spent too much time looking just for this ^^). Hope it will help someone :)
Please sign in or sign up for free to reply
tomgobich
Thanks for sharing Petzi!! 😊
Please sign in or sign up for free to reply