Ecto could not retrieve schema migrations data from Cassandra
We are trying to replace Postgres adapter with this one, but simple drop-in did not work:
14:32:27.613 [error] Cassandra.Connection (#PID<0.220.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.613 [error] Cassandra.Connection (#PID<0.226.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.222.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.224.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.225.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.221.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.223.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.227.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.219.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.614 [error] Cassandra.Connection (#PID<0.228.0>) failed to connect: ** (Cassandra.ConnectionError) TCP Connect :timeout
14:32:27.616 [error] Could not retrieve migrated versions. This error typically happens when the "schema_migrations" table, which Ecto uses for storing migrationinformation, is already used by another library or for other purposes.
You can fix this by running `mix ecto.drop` in the appropriate `MIX_ENV` to drop the existing database and let Ecto start a new one with a proper definition of "schema_migrations" or by configuring the repository to use another source:
config :annon_api, Annon.DB.Configs.Repo,
migration_source: "some_other_table_for_schema_migrations"
The full error is shown below.
** (Cassandra.ConnectionError) execute no connection
lib/ecto_cassandra/adapter.ex:26: EctoCassandra.Adapter.execute_ddl/3
(ecto) lib/ecto/migrator.ex:44: anonymous fn/2 in Ecto.Migrator.migrated_versions/2
(ecto) lib/ecto/migrator.ex:276: Ecto.Migrator.verbose_schema_migration/3
(ecto) lib/ecto/migrator.ex:148: Ecto.Migrator.run/4
(ecto) lib/mix/tasks/ecto.migrate.ex:84: anonymous fn/4 in Mix.Tasks.Ecto.Migrate.run/2
(elixir) lib/enum.ex:645: Enum."-each/2-lists^foreach/1-0-"/2
(elixir) lib/enum.ex:645: Enum.each/2
(mix) lib/mix/task.ex:294: Mix.Task.run_task/3
In tests i've used official docker Cassandra image, keyspaces were created successfully:
INFO [OptionalTasks:1] 2017-04-30 11:24:29,883 CassandraRoleManager.java:351 - Created default superuser role 'cassandra'
INFO [Native-Transport-Requests-1] 2017-04-30 11:24:35,208 MigrationManager.java:303 - Create new Keyspace: KeyspaceMetadata{name=annon_api_configs_test, params=KeyspaceParams{durable_writes=true, replication=ReplicationParams{class=org.apache.cassandra.locator.SimpleStrategy, replication_factor=1}}, tables=[], views=[], functions=[], types=[]}
INFO [Native-Transport-Requests-2] 2017-04-30 11:24:35,345 MigrationManager.java:303 - Create new Keyspace: KeyspaceMetadata{name=annon_api_logger_test, params=KeyspaceParams{durable_writes=true, replication=ReplicationParams{class=org.apache.cassandra.locator.SimpleStrategy, replication_factor=1}}, tables=[], views=[], functions=[], types=[]}
Other things I've noticed:
- This adapter doesn't use Ecto integration tests suite.
-
mix ecto.dropdoes not delete keyspaces - This adapter does not support
SQL.Sandbox, which is bad if you want to run lots of tests in parallel:
** (EXIT from #PID<0.70.0>) shutdown: failed to start child: Annon.DB.Configs.Repo.CassandraRepo
** (EXIT) shutdown: failed to start child: Cassandra.Session
** (EXIT) shutdown: failed to start child: Cassandra.Session.ConnectionManager
** (EXIT) an exception was raised:
** (UndefinedFunctionError) function Ecto.Adapters.SQL.Sandbox.start_link/2 is undefined or private
(ecto) Ecto.Adapters.SQL.Sandbox.start_link(Cassandra.Connection, [balancer: %Cassandra.LoadBalancing.TokenAware{wrapped: %Cassandra.LoadBalancing.RoundRobin{max_tries: 3, num_connections: 10}}, idle_timeout: 30000, queue: false, otp_app: :annon_api, repo: Annon.DB.Configs.Repo, adapter: EctoCassandra.Adapter, priv: "priv/repos/configs", contact_points: ["localhost"], replication: [class: "SimpleStrategy", replication_factor: 1], keyspace: "annon_api_configs_test", pool: Ecto.Adapters.SQL.Sandbox, cluster: Annon.DB.Configs.Repo.CassandraRepo.Cassandra.Cluster, session: Annon.DB.Configs.Repo.CassandraRepo.Cassandra.Session, cache: Annon.DB.Configs.Repo.CassandraRepo.Cassandra.Session.Cache, connection_manager: Annon.DB.Configs.Repo.CassandraRepo.Cassandra.Session.ConnectionManager, host: {172, 17, 0, 2}, pool_size: 10])
(cassandra) lib/cassandra/session/connection_manager.ex:114: Cassandra.Session.ConnectionManager.start_connection/3
(elixir) lib/enum.ex:1229: Enum."-map/2-lists^map/1-0-"/2
(cassandra) lib/cassandra/session/connection_manager.ex:101: Cassandra.Session.ConnectionManager.connect_to_up_hosts/1
(cassandra) lib/cassandra/session/connection_manager.ex:38: Cassandra.Session.ConnectionManager.init/1
(stdlib) gen_server.erl:328: :gen_server.init_it/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Issues can be reproduced by code from this PR.
Are you using this in along side a postgres repo?
About Ecto integration tests, they are heavily related to SQL databases and can't be used with Cassandra, as Cassandra has many restrictions on SELECT statement and primary keys.
Nope, I'm trying to replace PostgreSQL with Cassandra entirely.
Actually all tests are tagged and Ecto maintainers are welcome to merge any additional tags for integration tests, thus you can use them by excluding everything that you don't support.
Are you using this in along side a postgres repo? - Is this not possible? @hzamani