Skip to content
Evan Prothro edited this page Nov 20, 2015 · 12 revisions

Table Operations

Use create_table and drop_table to manage tables within your configured keyspace.

To create a table with a simple primary key, you may specify the key inline with the column.

class CreatePosts < CassandraMigrations::Migration
  def up
    create_table :posts do |p|
      p.integer :id, primary_key: true
      p.timestamp :created_at
      p.string :title
      p.text :text
    end
  end

  def down
    drop_table :posts
  end
end

And now run:

rake cassandra:migrate

To create a table with compound primary key, specify the primary keys on table creation, i.e.:

class CreatePosts < CassandraMigrations::Migration
  def up
    create_table :posts, primary_keys: [:id, :created_at] do |p|
      p.integer :id
      p.timestamp :created_at
      p.string :title
      p.text :text
    end
  end

  def down
    drop_table :posts
  end
end

To create a table with a compound partition key specify the partition keys on table creation, i.e.:

class CreatePosts < CassandraMigrations::Migration
  def up
    create_table :posts, partition_keys: [:id, :created_month], primary_keys: [:created_at] do |p|
      p.integer :id
      p.string :created_month
      p.timestamp :created_at
      p.string :title
      p.text :text
    end
  end

  def self
    drop_table :posts
  end
end

To create a table with a secondary index you add it similar to regular rails indexes, i.e.:

class CreatePosts < CassandraMigrations::Migration
  def up
    create_table :posts, primary_keys: [:id, :created_at] do |p|
      p.integer :id
      p.timestamp :created_at
      p.string :title
      p.text :text
    end

    create_index :posts, :title, name: 'by_title'
  end

  def self
    drop_index 'by_title'
    drop_table :posts
  end
end

Collections

Support for Cassandra collections are provided via the list, set and map column types.

class CollectionsListMigration < CassandraMigrations::Migration
  def up
    create_table :collection_lists do |t|
      t.uuid :id, :primary_key => true
      t.list :my_list, :type => :string
      t.set :my_set, :type => :float
      t.map :my_map, :key_type => :uuid, :value_type => :float
    end
  end
end

Additional Table Options

The create_table method allow do pass a hash of options for:

  • Clustering Order (clustering_order): A string such as 'a_decimal DESC'
  • Compact Storage (compact_storage): Boolean, true or false
  • Wait before GC (gc_grace_seconds): Default: 864000 [10 days]
  • Others: See CQL Table Properties

Cassandra Migration will attempt to pass through the properties to the CREATE TABLE command.

Examples:

class WithClusteringOrderMigration < CassandraMigrations::Migration
  def up
    create_table :collection_lists, options: {
                                      clustering_order: 'a_decimal DESC',
                                      compact_storage: true,
                                      gc_grace_seconds: 43200
                                    } do |t|
      t.uuid :id, :primary_key => true
      t.decimal :a_decimal
    end
  end
end

Column Operations

Use add_column and remove_column to alter existing tables.

class AddCategoryToPostsMigration < CassandraMigrations::Migration
  def up
    add_column :posts, :category, :text
  end

  def down
    remove_column :posts, :category
  end
end

Using Alternate/Additional Keyspaces

The using_keyspace method in a migration allows to execute that migration in the context of a specific keyspace:

class WithAlternateKeyspaceMigration < CassandraMigrations::Migration
  def up
    using_keyspace('alternative') do
      create_table :collection_lists, options: {compact_storage: true} do |t|
        t.uuid :id, :primary_key => true
        t.decimal :a_decimal
      end
    end
  end
end

If using multiple keyspaces, read about Using Multiple Keyspaces.

Using Raw CQL

If you need to alter your schema in a way not supported by the DSL, executing a CQL statement directly is recommended.

class CreateUserUDTMigration < CassandraMigrations::Migration
class Createudt < CassandraMigrations::Migration
  def up
    cql = %(
            CREATE TYPE user (
              username text,
              first_name text,
              last_name text,
              avatar_url text,
              birthdate timestamp
            );
           )
    announce_operation "create_type(user)"
    announce_suboperation cql.gsub(/\n\s*/, '').gsub(/,/, ', ')

    execute(cql)
  end

  def down
    cql = "DROP TYPE user;"
    announce_operation "drop_type(user)"
    announce_suboperation cql

    execute(cql)
  end
end
$ rake cassandra:migrate
== Createudt: migrating =======================================================
  create_type(user)
  -> CREATE TYPE user (username text, first_name text, last_name text, avatar_url text, birthdate timestamp);
== Createudt: migrated (0.0777s) ==============================================

Migrated 1 version(s) up.
$ rake cassandra:rollback
== Createudt: reverting =======================================================
  drop_type(user)
  -> DROP TYPE user;
== Createudt: reverted (0.0424s) ==============================================

Rolled back 1 version(s).