Skip to content
Nathan Brazil edited this page Apr 15, 2018 · 12 revisions

Types

Use the following type identifiers for fields. Call these methods on the table instance, or pass these as symbols or strings when other operations (e.g. add_column, remove_column):

  • text
  • integer
  • decimal
  • float
  • double
  • boolean
  • uuid
  • timeuuid
  • inet
  • timestamp
  • datetime
  • binary
  • list (use :type option)
  • set (use :type option)
  • map (use :key_type and :value_type options)

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

Compound primary key

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

Compound partition key

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

Secondary index

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.

Unsupported Operations

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

class CreateUserUDTMigration < 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
== CreateUserUDTMigration: migrating =========================================
  create_type(user)
  -> CREATE TYPE user (username text, first_name text, last_name text, avatar_url text, birthdate timestamp);
== CreateUserUDTMigration: migrated (0.0777s) ================================

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

Rolled back 1 version(s).

Additional Unsupported Operations

These operations are also available for use inside migrations:

  • execute_file(path) - This operation takes a file path string, reads in its content, and executes operations therein by calling #execute_text.
  • execute_statement(stmt) - This operation takes a single CQL statement as a string and executes it.
  • execute_text(text) - This operation takes a string consisting of multiple CQL statements delimited by semi-colons (;) and executes them one at a time.