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
- 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.
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