Sequel generate migration - ruby

I see that the Sequel gem supports migrations here, but I don't see any type of generator documented. Does one exist; or should I be manually creating all of my migrations (or alternately creating my own task to generate migrations)?

From the documentation:
Sequel doesn't come with generators that create migrations for you. However, creating a migration is as simple as creating a file with the appropriate filename in your migrations directory that contains a Sequel.migration call.
The contents of the migration file doesn't have to specify a timestamp or index and it's an extremely simple format.
I generally just copy a previous migration (maybe one similar to the migration I'm creating) and alter the filename. See existing migrations with:
$ ls -1 db/migrate/
20170320075430_check_postgres_extensions.rb
...
For running migrations, I use the rake task that's available here.

Sequel has no migration generator. But you can easily write your own, for example using a rake task. Here is one:
# Rakefile
require 'fileutils'
namespace :db do
MIGRATIONS_DIR = 'db/migrations'
desc "generates a migration file with a timestamp and name"
task :generate_migration, :name do |_, args|
args.with_defaults(name: 'migration')
migration_template = <<~MIGRATION
Sequel.migration do
up do
end
down do
end
end
MIGRATION
file_name = "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{args.name}.rb"
FileUtils.mkdir_p(MIGRATIONS_DIR)
File.open(File.join(MIGRATIONS_DIR, file_name), 'w') do |file|
file.write(migration_template)
end
end
end
Then run the rake task like this rake db:generate_migration[my_migration_name]. This command will create a Sequel migration file 20220720233750_my_migration_name.rb in the directory db/migrations.

Related

How to ignore a missing migration with "sequel -s"

I'm trying to use Sequel to manage migrations for my database, and sometimes, due to feature-branching, there are moments when the database has migrations applied that don't exist in the filesystem.
By default, when I apply migrations with sequel -m on those situations I get this error:
Error: Sequel::Migrator::Error: Applied migration files not in file system
"Migrations" says there's an option for that:
Ignoring missing migrations
In some cases, you may want to allow a migration in the database that does not exist in the filesystem (deploying to an older version of code without running a down migration when deploy auto-migrates, for example). If required, you can pass :allow_missing_migration_files => true as an option. This will stop errors from being raised if there are migrations in the database that do not exist in the filesystem.
Nice!
How do I pass that allow_missing_migration_files option to sequel -m?
I think you'll have to use the Sequel::Migrator API for that. Something like
Sequel::Migrator.run(DB, '/path/to/migrations/dir', allow_missing_migration_files: true)
You can also wrap this behavior in a Rake task, so you don't have to start a console to run migrations.
namespace :db do
desc "Run migrations ignoring the missing ones"
task :migrate_without_missing, [:version] do |t, args|
require "sequel"
Sequel.extension :migration
db = Sequel.connect(ENV.fetch("DATABASE_URL"))
if args[:version]
puts "Migrating to version #{args[:version]}"
Sequel::Migrator.run(db, "db/migrations", target: args[:version].to_i, allow_missing_migration_files: true)
else
puts "Migrating to latest"
Sequel::Migrator.run(db, "db/migrations", allow_missing_migration_files: true)
end
end
end
Then run rake db:migrate_without_missing.

execute task in .rb file

I'm working on a project that's been in development for quite a while now. I'm trying to figure out how everything works and my next step was how to update/fill the 'library' as it's called in the project.
I found several .rake files hidden away somewhere, but they are used in another .rb file. In said .rb file the entire logic behind the several tasks is set up, so everything happens in the right order.
Now, here's my problem: I need to use the tasks in the .rb file in order to generate the library. They're nested in namespaces and I can't figure out how to reach the tasks.
Here's a shortened version of the structure in the library.rb file:
namespace :library do
task :something do
...
end
...
namespace :local do
...
namespace :generate do
task :default do
...
end
end
end
end
I want to reach the task :default.
Thanks in advance for any help or advice.
EDIT:
The command rake library:local:generate:default gives an error:
rake aborted!
Don't know how to build task 'library:local:generate:default'
EDIT: I can't change the file's names, extentions or locations. Library.rb is currently located in config/deploy/
I'm assuming you would like to run the rake task from the command line, in which case you would enter rake library:local:generate:default.
You also need to require your library.rb file to make the task available. You can do that with the -f flag on the rake command. So, for example: rake -f path/to/library.rb library:local:generate:default.
A fast solution could be rename the file with .rake extension and put the file under lib/task so you can call it with rake namespace:task
namespace :library do
task :something do
...
end
...
namespace :local do
...
namespace :generate do
task default: :environment do
...
end
end
end
end
You forgot to add environment to it. Try the same rake task command again:
rake library:local:generate:default
This might help you

How can I load ActiveRecord database tasks on a Ruby project outside Rails?

ActiveRecord 3.2.14
I want to use ActiveRecord in a non-Rails Ruby project. I want to have available the rake tasks that are defined by ActiveRecord. How can I do that?
rake db:create # Create the database from DATABASE_URL or config/database.yml for the current Rails.env (use db:create:all to create all dbs in the config)
rake db:drop # Drops the database using DATABASE_URL or the current Rails.env (use db:drop:all to drop all databases)
rake db:fixtures:load # Load fixtures into the current environment's database
rake db:migrate # Migrate the database (options: VERSION=x, VERBOSE=false)
rake db:migrate:status # Display status of migrations
rake db:rollback # Rolls the schema back to the previous version (specify steps w/ STEP=n)
rake db:schema:dump # Create a db/schema.rb file that can be portably used against any DB supported by AR
rake db:schema:load # Load a schema.rb file into the database
rake db:seed # Load the seed data from db/seeds.rb
rake db:setup # Create the database, load the schema, and initialize with the seed data (use db:reset to also drop the db first)
rake db:structure:dump # Dump the database structure to db/structure.sql
rake db:version # Retrieves the current schema version number
The above list is the list of tasks that I want to be able to use on my non-Rails Ruby project that uses ActiveRecord. What do I have to write in my Rakefile?
Thanks in advance
The easiest thing to do is to load the tasks already defined in databases.rake. Here is a GIST of how it was done.
Inspired by this GIST by Drogus
Rakefile.rb
require 'yaml'
require 'logger'
require 'active_record'
include ActiveRecord::Tasks
class Seeder
def initialize(seed_file)
#seed_file = seed_file
end
def load_seed
raise "Seed file '#{#seed_file}' does not exist" unless File.file?(#seed_file)
load #seed_file
end
end
root = File.expand_path '..', __FILE__
DatabaseTasks.env = ENV['ENV'] || 'development'
DatabaseTasks.database_configuration = YAML.load(File.read(File.join(root, 'config/database.yml')))
DatabaseTasks.db_dir = File.join root, 'db'
DatabaseTasks.fixtures_path = File.join root, 'test/fixtures'
DatabaseTasks.migrations_paths = [File.join(root, 'db/migrate')]
DatabaseTasks.seed_loader = Seeder.new File.join root, 'db/seeds.rb'
DatabaseTasks.root = root
task :environment do
ActiveRecord::Base.configurations = DatabaseTasks.database_configuration
ActiveRecord::Base.establish_connection DatabaseTasks.env.to_sym
end
load 'active_record/railties/databases.rake'
You could try the standalone-migrations gem:
https://github.com/thuss/standalone-migrations
For Rails 3.x:
You need to manually create the tasks. As example here is how to add them (this example uses the environment variables like Rails):
namespace :db do
desc "Drop and create the current database"
task :recreate => :environment do
abcs = ActiveRecord::Base.configurations
ActiveRecord::Base.establish_connection(abcs[RAILS_ENV])
ActiveRecord::Base.connection.recreate_database(ActiveRecord::Base.connection.current_database)
end
end
and you'll have the task rake db:recreate available
For Rails 4.x:
If you want to have the ActiveRecord rake tasks available in your ruby app, take a look at the documentation.
Example usage of DatabaseTasks outside Rails could look as such:
include ActiveRecord::Tasks
DatabaseTasks.database_configuration = YAML.load(File.read('my_database_config.yml'))
DatabaseTasks.db_dir = 'db'
# other settings...
DatabaseTasks.create_current('production')
Also you have here an example on how to use ActiveRecord in your ruby aplication.
Create your own!
Reference the Rails one though:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake
Create a Rake Task file. To use Rake, generally you want a tasks folder filled with Rake task files. These files have the ".task" extension.
Study the file to link given.
Take parts of that file, or even the entire contents of the file, and add it to your new Rake task file.
Make sure your Rakefile loads those task files. Your Rakefile should have something like this
-
Dir[File.join(PROJECT_ROOT, 'tasks', '**', '*.rake')].each do |file|
load file
end
I believe you can use the sinatra-activerecord gem even if you're not using Sinatra. I just solved this problem by requiring that gem and then adding
require 'sinatra/activerecord/rake'
to my rakefile.
Once I added that require line the db tasks showed up in my rake -T!
If you are using Sinatra, you can use this gem:
https://github.com/janko-m/sinatra-activerecord
However, if you don't use it either, the source code inside provides a good example on how to implement AR rake tasks.

How to disable db:schema:dump for migrations

I dont want Rails 3 to generate my schema every time I do migration. How to properly disable it?
Thanks
For anyone who is still looking for a way to disable the db dump after migration a configuration is now available in rails 4 which can be set to false like this:
config.active_record.dump_schema_after_migration = false
will prevent it. The configuration has been added in this change - https://github.com/rails/rails/pull/13948
Create an application specific task (as Alex Kaushovik suggested) like so...
Create a file lib\tasks\db_schema_override (actual name doesn't matter, you need a .rake file in lib\tasks) with contents as below (credit to Matthew Bass for remove_task)
Rake::TaskManager.class_eval do
def remove_task(task_name)
#tasks.delete(task_name.to_s)
end
end
Rake.application.remove_task('db:schema:dump')
namespace :db do
namespace :schema do
task :dump do
# Overridden to do nothing
end
end
end
A modification based on David Waller's answer that retains the ability to run db:schema:dump manually. Covers all tasks where schema dumping is automatically invoked. Based on rails 3.2.14 versions of the relevant tasks - when you change rails versions, you'll want to ensure that the task definitions are still valid.
Seriously, there should be a config option to disable automatic schema dumps.
Rake::TaskManager.class_eval do
def remove_task(task_name)
#tasks.delete(task_name.to_s)
end
Rake.application.remove_task("db:migrate")
Rake.application.remove_task("db:rollback")
Rake.application.remove_task("db:forward")
Rake.application.remove_task("db:migrate:up")
Rake.application.remove_task("db:migrate:down")
end
namespace :db do
desc "Migrate the database (options: VERSION=x, VERBOSE=false)."
task :migrate => [:environment, :load_config] do
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, ENV["VERSION"] ? ENV["VERSION"].to_i : nil) do |migration|
ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope)
end
# db_namespace['_dump'].invoke
end
desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n).'
task :rollback => [:environment, :load_config] do
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
# db_namespace['_dump'].invoke
end
# desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
task :forward => [:environment, :load_config] do
step = ENV['STEP'] ? ENV['STEP'].to_i : 1
ActiveRecord::Migrator.forward(ActiveRecord::Migrator.migrations_paths, step)
# db_namespace['_dump'].invoke
end
namespace :migrate do
# desc 'Runs the "up" for a given migration VERSION.'
task :up => [:environment, :load_config] do
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
raise 'VERSION is required' unless version
ActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, version)
# db_namespace['_dump'].invoke
end
# desc 'Runs the "down" for a given migration VERSION.'
task :down => [:environment, :load_config] do
version = ENV['VERSION'] ? ENV['VERSION'].to_i : nil
raise 'VERSION is required' unless version
ActiveRecord::Migrator.run(:down, ActiveRecord::Migrator.migrations_paths, version)
# db_namespace['_dump'].invoke
end
end
end
I've tested the following - it works:
You could modify the file "databases.rake" inside of the Rails gem's lib/tasks folder on your server(s). Comment out lines with the following code:
Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
By default on Ubuntu (and Ubuntu server) it is here: /var/lib/gems/1.8/gems/rails-x.x.x/lib/tasks/databases.rake.
Tested with Rails 2.3.11, but I'm pretty sure it'll work with Rails 3.x.x too.
Another possible solution (didn't test):
You wouldn't have to modify Rails files, just your application.
A rails plugin called "override_rake_task" could be used to override Rake task "db:schema:dump" which is defined inside if Rails gem.
Apparently if you are not using this plugin and if you define a task in your rails application with the same name, rake would execute both tasks: the default and yours.
The default behavior of Active Record is to dump the schema, but it only does it if the schema dump format is set to ruby (the default).
You can disable the schema dump after migrations by setting the schema format to sql. You can safely reverse it to ruby after the migration finishes without consequences.
You can do it in this way:
1) If you have a line like this one setting explicitly the schema to ruby:
config.active_record.schema_format = :ruby
(it could be inside config/application.rb, on config/environment or in the specific environment you are running the migration in).
Then comment it out:
#config.active_record.schema_format = :ruby
2) Then add a line to set the schema format to SQL, either in the environment you are using, or at config/application.rb, as follows:
config.active_record.schema_format = :sql
Rather than overriding the db:migrate behavior (which is obviously necessary when you're building the migration in development, but unnecessary when deploying) I would suggest creating a separate task like:
# http://stackoverflow.com/questions/13646840/how-to-make-rake-dbmigrate-generate-schema-rb-when-using-sql-schema-format
namespace :db do
desc "Migrate the database, without dumping the schema.rb"
task :deploy => :environment do
ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
ActiveRecord::Migrator.migrate("db/migrate/", nil)
end
end
Then during your deployments you can simply do
rake db:deploy

calling a ruby file from a RakeFile

I'm creating an application which requires migrations without rails. For that I have created a rake file to execute commands.
My problem is how can I call a ruby class function from a rake file. I want something like this. consider both are in the same directory
class A
def b
puts 'calling method B from class A'
end
end
in the RakeFile
task :create do
A.new.b
end
I want to execute it as
rake create
But currently I'm getting this error
rake aborted!
no such file to load -- a
I'm using ruby 1.9.1, rake (0.8.7)
thanks in advance
cheers
sameera
Have you required the file containing the class? Meaning, have you used any statement like
require "path/to/a.rb" #where a.rb contains the class A
It seems like ruby converter unable to find where to look for class A.

Resources