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.
-
So there's not much purpose
-
in actually taking a look at them right now,
-
but if we were to try to,
-
so we can go in here, view data,
-
and click on first 100 rows,
-
it'll print it out, but it's just gonna be an empty table.
-
So again, not too much to look at right there.
-
If you wanted to, you could drop this down
-
where you can see the columns, constraints,
-
indexes, policies, rules, and triggers.
-
So we can expand the columns here
-
to see all of the different columns
-
that make up this particular table,
-
where we see our ID, role ID, full name, avatar URL,
-
email, password, created at, and updated at,
-
which matches what we had exactly in our migration.
-
So everything's looking a-okay here,
-
and we should be ready to move onward with our application.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
7.0The Flow of Middleware7m 49s
-
7.1Authenticating A Newly Registered User4m 14s
-
7.2Checking For and Populating an Authenticated User2m 10s
-
Logging Out An Authenticated User2m 24s
-
Logging In An Existing User6m 54s
-
Remembering A User's Authenticated Session6m 55s
-
Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
-
Creating A Movie List Page3m 43s
-
Filtering A Query By Pattern Likeness7m 9s
-
Filtering Our List by Movie Status5m 47s
-
How To Apply A Dynamic Sort Filter To Your Query7m 12s
-
Joining SQL Tables To Order By A Related Column4m 49s
-
Validating Query String Filter Values7m 23s
-
How To Paginate Filtered Query Results9m 15s
-
Pagination First, Last, Next, and Previous Buttons4m 2s
-
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!