Add schema reflection API on nullable fields/associations

18 views
Skip to first unread message

Arno Dirlam

unread,
May 15, 2024, 9:00:33 AMMay 15
to elixir-ecto
Hello,

I'm developing a library that generates Ecto queries from Elixir code (in dx, search for `import Dx.Defd`).
It would be really helpful to have knowledge about the nullability of an Ecto schema field or association, either at compile-time or runtime.
This will probably be just as helpful for the Elixir type system that's currently work in progress.


Option 1: Add `:null` flag to Ecto schema fields (`Ecto.Type`)

Pros:
  • in line with existing schema reflection API
    • The reflection API could be `__schema__(:null)`
  • same flag as used in schema migration API
  • available at compile-time
Cons:
  • depends on the user to keep the flags up-to-date
    • especially removing a `null: false` flag when changing the column to `null: true` in the database

Option 2: Query & cache database schema at runtime

Pros:
  • Correct without depending on the user setting and maintaining flags
Cons:
  • introduces new infrastructure within Ecto
    • supervisor, ETS table or similar
  • needs to be implemented in each database adapter
  • not available at compile-time
  • raises questions about cache invalidation
    • hot code deploys?
    • database schema changing without the app being restarted?

Seems like Option 1 would be the way to go. Are there any other options?
Anything I'm overlooking?

Grateful for any feedback!


Best wishes from Berlin,
Arno

José Valim

unread,
May 15, 2024, 9:04:58 AMMay 15
to elixi...@googlegroups.com
It will definitely be useful for the type system, so we plan to introduce it then, but not before (I am sorry but it is probably better to design them together). Meanwhile, you can have something that replaces Ecto.Schema field, by our own field, that injects null for now.


Arno Dirlam

unread,
May 15, 2024, 2:42:54 PMMay 15
to elixir-ecto
Thanks a lot for the swift and clear response, José! 🙏

something that replaces Ecto.Schema field, by our own field, that injects null

am I on the right track with parameterized types like this?

field :name, Dx.Schema.Field, base: :string, null: false
belongs_to :category, type: Dx.Schema.BelongsTo, base: Category, null: false

and internally

defmodule Dx.Schema.BelongsTo do
use Ecto.ParameterizedType

def type(_params), do: Ecto.Association.BelongsTo
# ...
end


Thank you!

Arno

José Valim

unread,
May 15, 2024, 5:35:48 PMMay 15
to elixi...@googlegroups.com
I was thinking more like:

defmodule MyMacro do
  defmacro field(field, type, opts \\ []) do
    quote bind_quoted: [field: field, type: type, opts: opts] do
      {null?, opts} = Keyword.pop(opts, :null)
      MyMacro.store_nil(__MODULE__, field, null?)
      Ecto.Schema.field(field, type, opts)
    end
  end
end

What you replace Ecto's field and define your own fields with.

--
You received this message because you are subscribed to the Google Groups "elixir-ecto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-ecto...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-ecto/4e0be705-2e25-4e53-98e4-d1ce0ab0205fn%40googlegroups.com.

Arno Dirlam

unread,
May 20, 2024, 3:06:43 PMMay 20
to elixir-ecto
Thanks a lot for the pointer, José! 🙏
Reply all
Reply to author
Forward
0 new messages