Cassandra Migrations is a Cassandra database schema migration library for Rails applications.
This gem provides:
- Multi-environment database configuration
- Versioned CQL schema migration management
- A schema modification DSL for simplified migration code
- Rake tasks for database schema management
- Support for forked processes
Use Cassandra in an organized and familiar way, without changing how you work with your ActiveRecord relational database schema.
- Cassandra >= 1.2, using the native transport protocol
- Ruby >= 1.9
- Rails >= 3.2
gem install cassandra_migrations
or, with bundler, add the following to your gemfile:
gem 'cassandra_migrations'
Similar to how config/database.yml
stores your relational databse configuration, config/cassandra.yml
stores your cassandra database configuration.
rails g cassandra_configuration
This will create the config/cassandra.yml
with default settings. Configure the database names for each of your environments.
development:
hosts:
- 127.0.0.1
port: 9042
keyspace: my_keyspace_dev
replication:
class: SimpleStrategy
replication_factor: 1
These are the minimum options to get started, for advanced configuration, read about [Database Configuration Options](wiki/Database Configuration Options).
Assuming your Cassandra database is running, you may now create your keyspace:
rake cassandra:create
Similar to how db/migrate/
stores your relational databse schema migration files, db/cassandra_migrate/
stores your Cassandra schema migration files.
rails g cassandra_migration create_posts
This will create a versioned migration in db/cassandra_migrate/
, with familiar up
and down
methods that will be executed when applying or rolling back a migration, respectively.
class CreatePosts < CassandraMigrations::Migration
def up
end
def down
end
end
You may call execute
from these methods to execute CQL statements to your configured keyspace.
For increased readability and ease of use, there is also a familiar DSL available from the migration methods.
class CreatePosts < CassandraMigrations::Migration
def up
create_table :posts,
partition_keys: [:id, :created_month],
primary_keys: [:created_at] do |t|
t.integer :id
t.string :created_month
t.timestamp :created_at
t.string :title
t.string :category
t.set :tags, type: :float
t.map :my_map, key_type: :uuid, value_type: :float
t.text :content
end
create_index :posts, :category, name: 'posts_by_category'
end
def down
drop_index 'posts_by_category'
drop_table :posts
end
end
Use the following type methods for fields:
text
integer
decimal
float
double
boolean
uuid
timeuuid
inet
timestamp
datetime
binary
list
(withtype
option)set
(withtype
option)map
(withkey_type
andvalue_type
options)
For more details on the DSL's types, advanced table options, keyspace manipulation, or other schema statment methods, read about the [Migration DSL](wiki/Migration DSL).
There are a collection of familiar rake tasks to help you manage your cassandra databases.
rake cassandra:create
Creates the configured keyspace inconfig/cassandra.yml
.rake cassandra:drop
Drops the configured keyspace inconfig/cassandra.yml
.rake cassandra:migrate
Runs migrations that have not run yet.rake cassandra:rollback
Rolls back the latest migration that has been applied.rake cassandra:migrate:reset
Runscassandra:drop
,cassandra:create
andcassandra:migrate
.
Each rake task will be run against the database that is configured for the current environment (via RAILS_ENV
).
rake cassandra:migrate
== CreatePosts: migrating =====================================================
create_table(posts)
-> CREATE TABLE posts (id int, created_month varchar, created_at timestamp, title varchar, category varchar, content text, PRIMARY KEY((id, created_month), created_at))
create_index(posts)
-> CREATE INDEX posts_by_category ON posts (category)
== CreatePosts: migrated (0.3448s) ============================================
Migrated 1 version(s) up.
For more details on available rake tasks and options, read about [Rake Tasks](wiki/Rake Tasks).
When a migration requires working with data, not just schema, one option is using the Cassandra Migration query classes.
CassandraMigrations::Cassandra.select(:posts)
new posts = CassandraMigrations::Cassandra.select(:posts,
projection: 'title, created_at',
selection: 'id > 1234',
order_by: 'created_at DESC',
limit: 10
)
new_posts.each do |post|
CassandraMigrations::Cassandra.update!(:posts,
"id = #{post['id']}",
{tags: ['new']},
{operations: {tags: :+}})
end
For more details, options, and examples, read about the [Query Helpers](wiki/Query Helpers).
Cassandra Migrations has built-in support for Passenger's forked process model (e.g. smart spawning).
Each fork should contain its own session to avoid deadlock and other issues. Restart the connection after the process has forked.
# config/puma.rb
on_worker_boot do
# re-establish the connection in this process fork
CassandraMigrations::Cassandra.restart
end
To add cassandra database creation and migrations steps to your Capistrano recipe, add the following line to you deploy.rb:
require 'cassandra_migrations/capistrano'
To run the test suite:
bundle install
rake
Additionally, this project aims for compatiblity with Rails 3.2 and above. For that, we use the appraisal
gem. If you make changes, run our test suite against all supported version of Rails like so:
appraisal install
appraisal rake
- Henrique Gubert - @hsgubert
- Brian Sam-Bodden - @bsbodden
- Sid Tantia - @sstgithub
- Nathan Brazil - @bitaxis
- and more...
This gem is built upon the official Ruby Driver for Apache Cassandra by DataStax. Which supersedes the cql-rb gem (thank you Theo for doing an awesome job).