Is there any way to dynamically create and use models in Phoenix? I have an application that stores metadata about clients' tables: they set a handful of fields (column names and types) and then send me CSV files to parse and store. From the stored metadata, I'd like to generate a model so that I can use Ecto to manage the client table and perform queries against it.
I'm coming from a Django background where I can use the built in ORM and type()
function to build models on the fly and then use them without having to generate migrations or other model code in the application.
In Python, I would (roughly) do:
class MetaModel(models.Model):
table_name = models.CharField(...)
model_name = models.CharField(...)
field_defs = JSONField(...)
def resolve_fields(self):
# takes values from `field_defs` and converts them into
# django field instances
def get_model(self):
class Meta:
app_label = 'dynamic'
db_table = self.table_name
fields = self.resolve_fields()
attrs = {'__module__': 'dynamic', 'Meta': Meta}
attrs.update(fields)
model = type(self.model_name, (models.Model,), attrs)
return model
def create_table(self):
with connection.schema_editor() as se:
model = self.get_model()
se.create_model(model)
With that, I'm able to create the table in the database and then leverage the ORM to work with client supplied data.
I know I can do it with raw SQL and just use Ecto to run the commands and queries, but I'd like to make it more codified and rely on the internals of Ecto rather than writing and maintaining a bunch of SQL templates.
Any advice (even a "nope, you can't do that") is super helpful. Thanks!