I would like to know if there is a specific command for rails db:migrate:reset.

I used the following article as a reference.

What is “ar_internal_metadata”, a table automatically generated in DB with Rails5
sell
Ruby
,
Rails
scivola
The development team I belong to is currently migrating its own service to Rails5. The other day, when I happened to look at the DB, I noticed that there was an unfamiliar table called “ar_internal_metadata”. The table information is as follows.

ar_internal_metadata
key value created_at updated_at
environment development 2016-08-13 18:42:31 2016-08-13 18:42:31
It seems that it only holds the information of the environment.

It was a DB accidental deletion prevention function added in Rails 5
I was curious, so I looked it up. Apparently, it is a new function added from Rails5, and it seems to be a table necessary for the function to prevent accidental deletion of DB.

Specifically, when the environment is production, executing the following tasks will throw an exception (there may be others).

drop: all
drops
purge: all
purge

RAILS_ENV=production rails db:drop

rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your ‘production’ database.
If you are sure you want to continue, run the same command with the environment variable:
DISABLE_DATABASE_ENVIRONMENT_CHECK=1
bin/rails:5:in require' bin/rails:5:in
Tasks: TOP => db:check_protected_environments
(See full trace by running task with --trace)
To pass the task, just specify “DISABLE_DATABASE_ENVIRONMENT_CHECK=1” as in the warning.

DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop
By default, exceptions are thrown only in production environments, but you can change this to whatever you want. For example, to include the staging environment, add the following description to “config/application.rb”.

config/application.rb
ActiveRecord::Base.protected_environments = %w(production staging)
Also, to check if your current environment is protected (does db:drop throw an exception), you can find out by doing the following tasks:

rails db:check_protected_environments # Raise exception if protected.
I also want a table deletion accidental explosion prevention function…

I used the following article as a reference.

rails db:migrate:reset failed so rails db:reset
sell
Ruby
,
Rails
,
SQLite3
from the conclusion
If an error occurs when migrating the db, attempting to reset the db and migrate at the same time with rails db:migrate:reset may fail.
There may be a problem with the execution order in the migration file, so it may be possible to solve it by performing rails db:reset and rails db:migrate separately.

environment
Rails 5.1.2
Ruby 2.4.3

what happened
Error in migration
When I was proceeding with the rails tutorial and tried to migrate the db, I got this error.

$ rails db:migrate

== 20171229141042 CreateUsers: migrating ======================================
– add_index(:users, :email, {:unique=>true})
→ 0.0010s
– create_table(:users)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: table “users” already exists: CREATE TABLE “users” (“id” INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, “name” varchar, “email” varchar, “created_at” datetime NOT NULL, “updated_at” datetime NOT NULL)


I’m getting angry that I’m trying to create a user table when it already exists.

Error even with reset:migration
So I tried rails db:migrate:reset.
(This command is mentioned in chapter 7.4.3 Real user registration)

$ rails db:migrate:reset

Dropped database ‘db/development.sqlite3’
Dropped database ‘db/test.sqlite3’
Created database ‘db/development.sqlite3’
Created database ‘db/test.sqlite3’
== 20171229141042 CreateUsers: migrating ======================================
– add_index(:users, :email, {:unique=>true})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: no such table: main.users: CREATE UNIQUE INDEX “index_users_on_email” ON “users” (“email”)


Also, I was angry that there was no users table.

Looking at the flow of processing, we are trying to add an index after deleting and recreating the DB. And the process to create the users table has not been done.

take a look at the migration file
Looking at the migration file, I found the cause.

I have added_index before creating the users table.
It seems that it is caused by various operations on the DB before creating the migration file while proceeding with the rails tutorial.

class CreateUsers < ActiveRecord::Migration[5.1]
def change
add_index :users, :email, unique: true
create_table :users do |t|
t. string :name
t. string : email

   t.timestamps
 end

end
end
What you wrote here helped me.

I could fix the migration like in the article above, but the official says it’s not recommended, and I’ve already touched the data here and there, so I solved the error by following the steps below.

try rails:db:reset
$rails:db:reset

Dropped database ‘db/development.sqlite3’
Dropped database ‘db/test.sqlite3’
Created database ‘db/development.sqlite3’
Created database ‘db/test.sqlite3’
– create_table(“users”, {:force=>:cascade})
→ 0.0036s
– create_table(“users”, {:force=>:cascade})
→ 0.0021s
The DB was deleted and recreated, and the users table was successfully created.
If you migrate after this, it will succeed without problems because the users table exists.

Difference between rails db:reset and rails db:migration:reset
Both rails db:reset and rails db:migration:reset are commands to recreate after deleting all DB, but there are the following differences.

About rails db:reset
rails db:reset creates DB based on db/schema.rb. db/migrate/**.rb is not used.

Rails Guides has the following description:

The bin/rails db:reset task drops and reconfigures the database. This task is equivalent to bin/rails db:drop db:setup.

This task is not equivalent to running all migrations. This is because this task reuses the current contents of schema.rb. If the migration cannot be rolled back, it may not be possible to recover by running bin/rails db:reset. For more information on schema dumps, see the Significance of Schema Dumps section.

4.3 Reset the database

Check the documentation of the rails db:setup command (4.2 Setting up the database) as it is synonymous with rails db:drop db:setup.

Create database
Schema loading
Initializing the database with seed data
It is written that the three processes of are executed.

About rails db:migrate:reset
On the other hand, rails db:migrate:reset seems to execute db/migrate/**.rb from the oldest after deleting the DB.
This seems to be used when you want to apply a new migration after deleting the DB once when you modify the migration file.
By the way, this command was not listed in the latest Rails Guides and was only listed in the Rails 4 series document.

It doesn’t exist even if you search with rails -T.

There is an instruction to execute this command in the English version of the 5 series tutorial, but is it actually treated as a secret command…?

at the end
I think that the method of executing commands separately for reset and migrate should be used in the early stages of development when data is touched here and there.

In order to solve the root cause of the error, it is necessary to check the DB and migration files and correct the inconsistencies.

What I researched and deduced =

Conclusion
①In fly.io, isn’t it possible to have the behavior corresponding to rails:db:migrate:reset in the first place?
②If possible, please let me know.
(3) If the scale of the app is for personal use or hobby use, wouldn’t it be quicker to delete the app itself and redeploy it?
④ But if there is a way, please tell me.

Reason for ①
In the first place, when deploying with fly.io, the app name and db are displayed on the dashboard. That is because I thought that the behavior of resetting the db, which I was trying to do casually, could not be done in the first place.

The reason why I thought there was a command that corresponds to rails:db:migrate:reset is because heroku also had it. I felt that the premise that heroku could do it and fly.io couldn’t do it was wrong.

Is my perception wrong?
Please give me some tips and wisdom.
Thank you all for your support.

rake db:migrate:reset drops the database, which isn’t something people typically do in a production environment. Postgres won’t let you drop a database when you have other apps connected, and PG databases on Fly typically have connections from multiple places.

If the goal is to clear out your db and rerun migrations, you may have better luck doing using just the migrate command. Find the first migration version, then run:

rake db:migrate VERSION=<version>

Then run migrate again to bring it back up:

rake db:migrate

This will only work if you keep all your old migrations around. You can create a rake task to run these two steps if you’d like.

I would suggest you try this with fly ssh console ... first, just to make sure it does what you want. Release commands on fly are harder to debug than commands you run with SSH.

1 Like

thank you. Kurt
I’ll read it carefully.
And I’ll try.
If you have any other points to point out, please let me know.

Is your intention something like the following?

shinichikikukawa@ShinichinoMacBook-Pro Attendance_System_A % fly ssh console -C “/app/bin/rails rake db:migrate VERSION=<1>”

I probably understood about 50% of what you said. Please tell me the remaining 50%.

I’m assuming your intent is to define the appropriate tasks in the fly.rake file and then run rake db:migrate?

for example,
task :setmigrate => ‘db:migrate VERSION1’

And in the fly.rake file, are you saying that you should try migrate in two steps?

Yes, you should run migrate and target the first migration version in your app. This will undo all the migrations. Then you run migrate with no version argument, and it will run all the migrations in sequence.

1 Like

It doesn’t seem to work if you don’t define your tasks properly.
From our conversations so far, we know that we can define tasks in fly.rake and run them on the console.

If kurt were to define a task in this case, how would it be defined?

shinichikikukawa@ShinichinoMacBook-Pro Attendance_System_A % fly ssh console -C "/app/bin/rails rake db:migrate VERSION=<1>"  
Update available 0.0.442 -> 0.0.443.
Run "fly version update" to upgrade.
Connecting to fdaa:1:1294:a7b:9b:eb93:113f:2... complete
rails aborted!
Don't know how to build task 'rake' (See the list of available tasks with `rails --tasks`)
/app/vendor/bundle/ruby/2.7.0/gems/railties-5.1.7/lib/rails/commands/rake/rake_command.rb:21:in `block in perform'
/app/vendor/bundle/ruby/2.7.0/gems/railties-5.1.7/lib/rails/commands/rake/rake_command.rb:18:in `perform'
/app/vendor/bundle/ruby/2.7.0/gems/railties-5.1.7/lib/rails/command.rb:46:in `invoke'
/app/vendor/bundle/ruby/2.7.0/gems/railties-5.1.7/lib/rails/commands.rb:16:in `<top (required)>'
/app/bin/rails:10:in `require'
/app/bin/rails:10:in `<main>'
(See full trace by running task with --trace)
shinichikikukawa@ShinichinoMacBook-Pro Attendance_System_A % 

fly.rake

# commands used to deploy a Rails application
namespace :fly do
  # BUILD step:
  #  - changes to the filesystem made here DO get deployed
  #  - NO access to secrets, volumes, databases
  #  - Failures here prevent deployment
  task :build => 'assets:precompile'

  # RELEASE step:
  #  - changes to the filesystem made here are DISCARDED
  #  - full access to secrets, databases
  #  - failures here prevent deployment
  task :release => 'db:migrate'
  
  task :disable_database_environment_check do
    ENV['DISABLE_DATABASE_ENVIRONMENT_CHECK'] = '1'
  end

  task :setmigrate => 'db:migrate VERSION1'
  

  task :reset => [
    'fly:disable_database_environment_check',
    'db:migrate:reset',
    'db:migrate',
    'db:seed'
  ]
  # SERVER step:
  #  - changes to the filesystem made here are deployed
  #  - full access to secrets, databases
  #  - failures here result in VM being stated, shutdown, and rolled back
  #    to last successful deploy (if any).
  task :server => :swapfile do
    sh 'bin/rails server'
  end

  # optional SWAPFILE task:
  #  - adjust fallocate size as needed
  #  - performance critical applications should scale memory to the
  #    point where swap is rarely used.  'fly scale help' for details.
  #  - disable by removing dependency on the :server task, thus:
  #        task :server do
  task :swapfile do
    sh 'fallocate -l 512M /swapfile'
    sh 'chmod 0600 /swapfile'
    sh 'mkswap /swapfile'
    sh 'echo 10 > /proc/sys/vm/swappiness'
    sh 'swapon /swapfile'
  end
end

I’ll try to think for myself
when i get home from work.

I think it’s easier to drop the database using psql, it’s as simple as “DROP DATABASE [dbname]”.

1 Like

Thank you for your advice.

Since I am a beginner in personal development, my knowledge of databases is still lacking.
In the first place, I imagined that the database would not be reset unnecessarily in the production environment, but I understand well.

I’m googling a lot.
Even an amateur thinks that the app name and DB name are displayed on the fly.io dashboard, so it is not possible to define a command worthy of rails:db:migrate:reset in the fly.rake file. Is it correct to assume that it will take a long time?

It might be easy if someone sees it.

If anyone has any idea how to do this, please help me.

I also needed to reset the staging database. The simple 5 steps I did:

  1. delete the database application (YOUR_APP_NAME-db) via fly dashboard
  2. run fly pg create that recreates an app with the PostgreSQL database
  3. run fly secrets set DATABASE_URL=HERE_THE_URL_TO_DB_FROM_STEP_2
  4. run fly ssh console -C 'app/bin/rails db:create'
  5. run fly ssh console -C 'app/bin/rails db:migrate'

that’s all. good luck.

2 Likes

Thank you Mateusz.
I’ll try it when I get home from work.
thank you for the advice!

I tried it after that, but I felt that it was going very well until the middle. However, I get an error that the app cannot be found.

hypothesis
Even though I was taught 5 simple steps, I stumbled on step 3. I believe that if this is firmly tied, we can go.

run fly secrets set DATABASE_URL=HERE_THE_URL_TO_DB_FROM_STEP_2

I pasted the URL generated in step 2 and typed the command.

I thought I was right.
But I got an error.

From an expert’s point of view, they may be able to notice the mistake, but in this respect, I am not able to do so due to my lack of knowledge and experience. I think something is wrong with me.

Please let me know my mistake.
Please lend me your strength.

I have confirmed that the docker file, fly.rake and fly.toml? have disappeared. It seems that the binding is not working properly.
The fly.io dashboard shows the app and app-db and they exist.

it looks like you run the console command from another directory than the app directory. That’s probably why fly can’t find the app. Try running the command from the app directory (the one with fly.toml in it that contains the app name). Alternatively, run command with -a APP_NAME parameter, example:

fly secrets set DATABASE_URL="postgres://postgres:uY1C×××GLNrprSC@attendance-system--a-db.internal:5432" -a attendance-system--a

BTW: after you have it running please redo all the steps and NEVER SHARE CREDENTIALS ON FORUMS. right now everyone on this forum can access your DB.

1 Like

thank you.

I would like to confirm the assumptions.

What I recognize based on facts (I may be wrong or misunderstood.) =
The simple 5 steps I did:

1.delete the database application (YOUR_APP_NAME-db) via fly dashboard
→ Executed.
As a result, the docker file, fly.rake and fly.toml disappeared.
I think this is the point, but at this point, if the docker file, fly.rake and fly.toml disappear, the following 4 steps will be meaningless, right? I apologize if I’m wrong or misunderstood.

  1. run fly pg create that recreates an app with the PostgreSQL database
    → It seems that a new db has been created.

3.run fly secrets set DATABASE_URL=HERE_THE_URL_TO_DB_FROM_STEP_2
→ As you pointed out, I understand that it should be executed in the directory where the fly.toml file is located. However, in step 1, if the essential fly.toml file disappears, isn’t it possible? I apologize if I misunderstood.

4.run fly ssh console -C ‘app/bin/rails db:create’
→ I stumbled in step 3, so I can’t execute it
5.run fly ssh console -C ‘app/bin/rails db:migrate’ → Unable to run because it stumbled in step 3

The situation is as above.
Here’s what I’d like to clarify:
1.delete the database application (YOUR_APP_NAME-db) via fly dashboard
→ Executed.

As a result, the docker file, fly.rake and fly.toml disappeared.

I think that’s the point here.

Why do the docker files, fly.rake and fly.toml disappear at this point?

Is it like that?

1.delete the database application (YOUR_APP_NAME-db) via fly dashboard

The question is whether the docker file, fly.rake and fly.toml will normally not disappear even if you run them.

I would like to find out why the docker file, fly.rake and fly.toml disappeared.

BTW: after you have it running please redo all the steps and NEVER SHARE CREDENTIALS ON FORUMS. right now everyone on this forum can access your DB.

I would like to turn it off.
Thanks for your advice.

thank you for your hard work.
I thought about it and researched it, but the conclusion is that I will delete the app once and start again.

I would be happy if someday, if there is something I can find out, I can share the method for the development of the community.

Thank you for your advice on various aspects.

If there’s something I should try, feel free to let me know. I will improve thank you.