Qqwy

Qqwy

TypeCheck Core Team

Ecto-less migrations?

Hello everyone!

As you might or might not know, Planga is a thing we’re building: It’s a seamless chat integration service.

Currently, I am busy working out the details of making Planga as scalable as it can be.
As has been discussed before in Mnesia vs Cassandra (vs CouchDB vs ...) - your thoughts?, we’re currently in the process of moving away from Mnesia to some other type of (decentralized!) datastore.

However, this brings two problems with it:

  1. It’s nearly impossible to use Ecto. On one hand, there do exist a couple of Ecto wrappers for these datastores, but they are experimental at best. (And we already are experiencing this with the ecto_mnesia wrapper… migrations are a pain and setting up the database in the testing environment is a mystery I haven’t solved yet). On the other: Distributed datastores are quite far away from what Ecto (2.0) is commonly used for: Queries (some are supported, many are not because of the data format of these decentralized datastores), Migrations (if you have your database in multiple nodes, it is near-impossible to migrate ‘tables’ at the same time).

We will still be using Ecto for its validations, but we probably will have to manage our database insertions/lookups/updates manually.

  1. Migrations. Planga is supposed to scale. We try to plan ahead as good as we can, but I am certain that there will be more fields added to our datastructures in the future.

However, this poses a problem: Once you have millions of messages stored in a (distributed) datastore, data migrations are near-impossible to run.
Instead, I currently think it makes more sense to define a way to version the datastructures, and allow older versions of the data structures to be transformed to the new expected format once it has been fetched from the datastore.
In this way, except in some advanced features where we need to add new indexes to the datastore or something, iterating over all datastructure in the datastore becomes unneccesary.

But now my question: What would be the best way to set up something like this? It feels like something that belongs in the Schema file at least. I am currently thinking about adding multiple heads for a function, one for every ‘version’ of the datastructure, which are then called incrementally (the version being an integer) until the ‘current’ version is reached.

Has someone experience with these kinds of things? I think it is sort of similar to the code_change function that is part of the GenServer behaviour, but then it is part of the data-layer rather than the code-layer.

Help is greatly appreciated!

Most Liked

jeremyjh

jeremyjh

I think your idea is a good one. It reminds me a little bit of the Haskell library SafeCopy. They use TH (macros) to generate typeclass implementations and I suppose you could possibly do something similar with protocols, but I think a new function head that just knows how to migrate to the next version would make more sense. I’d probably make separate named, versioned structs for each version so it is clear what kind of structures each migration clause is operating on. This may seem like a lot of overhead but you could tuck older versions away in a separate file.

Where Next?

Popular in Questions Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
gonzofish
I’m currently trying to understand how to join three tables using Ecto. All the examples I’ve seen use 2, so maybe I’m just missing somet...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New

Other popular topics Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement