I’m currently using Ecto in a project for data validation and rendering into Phoenix only (i.e., only using Ecto.Schema and Ecto.Changeset). This works well, but my schema allows for one field to be any valid term object, constrained by the value of another field. From what I can gather in the docs, Ecto.Schema requires a type, but my schema is not as rigid as this requirement.
Finally, schemas can also have virtual fields by passing the virtual: true option. These fields are not persisted to the database and can optionally not be type checked by declaring type :any .
The original poster sounded like they weren’t expecting to persist this data, just interacting with changesets.
But if necessary, it’s possible to make it work - set up an underlying column that accepts a binary value (some DBs will call that a BLOB, not all) and then write an Ecto type that uses Erlang Term Format:
DO NOT use this if the field can be written to by users. Deserializing user-controlled ETF is potentially Very Bad for security
DO NOT use this for historical data storage with structs; deserializing those when the underlying definition has changed can cause errors. If you must retain this data for a long time, normalize everything to basic types (maps, tuples, etc) with stable definitions
DO NOT use this if you need to query the data from SQL. It’s probably possible to write a PL/SQL function that parses ETF, but needing to query is a good sign this is not the right format for your application.
We use this at work for database persistence of the state of GenServers that only live for a single day; saves writing a lot of serialization / deserialization code.