Over the weekend I spun up a new Elixir :ecto, "2.2.7" project that I was able to get working with CockroachDB and this adapter fork - with some caveats I wanted to share to help others.
-
Only the
rootuser can create databases This requires you configure theEcto.Adapters.Postgresusernameasrootor else themix ecto.createcommand will always fail. You can go back and change your configuredusernameto something else after the database has been created, or create your database and user permissions usingcockroach sqland skip themix ecto.createcommand. -
Configuring Ecto primary_key ID to be created by CockroachDB By default when configuring your
Ecto.Schemausingautogenerate: falseit appears either CockroachDB, Ecto or the Postrex adapter (I did not investigate this) uses theBIGINTunique_rowid()function as the default value for IDs
@primary_key {:id, :id, autogenerate: false, read_after_writes: true}
@foreign_key_type :idTo auto-generate unique row IDs, use the UUID column with the gen_random_uuid() function as the default value:
Configure your Ecto.Schema as:
@primary_key {:id, :binary_id, autogenerate: false, read_after_writes: true}
@foreign_key_type :binary_idgen_random_uuid() as your binary_id primary_key type you will also need to configure your Ecto Migrations manually telling Ecto not to create your primary_key ID and add an SQL fragment:
create table(:comments, primary_key: false) do
add :id, :uuid, primary_key: true, default: fragment("gen_random_uuid()")
- Ecto Associations Due to some CockroachDB limitations/features I had to create a couple Ecto Migration files and do some manual configuration to get Ecto Associations to work.
It appears the Ecto references function always attempts to alter the COLUMN TYPE and TYPE changes on ALTER TABLE & ALTER COLUMN are not currently supported by CockroachDB. This causes an error on the sequence to create the foreign_key associations. CockroachDB also does not support adding REFERENCES from an Ecto alter command, so I could NOT just create the REFERENCE COLUMN ID in the main migration and then:
alter table(:comments) do
modify :post_id, references(:posts, on_delete: :nothing, type: :uuid)
endTo work around this I needed to:
- Add the
referenceto the initial migration:
create table(:posts, primary_key: false) do
add :id, :uuid, primary_key: true, default: fragment("gen_random_uuid()")
...
add :comment_id, references(:comments, on_delete: :nothing, type: :uuid)
- Then create an additional Ecto Migration to add the 'foreign_key' ID column:
alter table(:comments) do
add :post_id, :uuid
end
create index(:comments, [:post_id])- Then create one last Ecto Migration to create the DB CONSTRAINT REFERENCE manually using the
executefunction:
def change do
execute("ALTER TABLE comments ADD CONSTRAINT comments_id_fkey FOREIGN KEY (post_id) REFERENCES posts(id)")
endAs I am finishing this up I realize this is more suitable for a blog post with an example repo - but the kids are up from their naps so I will save this here and revisit later.
https://github.com/jumpn/postgrex
https://hexdocs.pm/postgrex_cdb/readme.html
Note that UUID arrays (as in Ecto assoc) are not supported in CockroachDB < 2.0
cockroachdb/cockroach#23063