I have a box
type in my postgres database, which i’m trying to map to my schema. I saw that Postgrex have a Postgrex.Extensions.Box, and tried to include it as follows:
config :my_app, MyApp.Repo,
adapter: Ecto.Adapters.Postgres,
extensions: [Postgrex.Extensions.Box],
...
and the use it
schema "foobar" do
field :bounding_box, :box
# ...
end
but with no luck.
** (ArgumentError) invalid or unknown type :box for field :bounding_box
Tried multiple variants of the type, e.g {:array, %Postgrex.Box{}}
which includes the struct, but no luck there as well.
Any help appreciated!
1 Like
There is Postgrex Extension doc here.
I am not sure if it can compare… but I used postgis extension lately. To make it work, I added a lib/postgres_types.ex
Postgrex.Types.define(LabDb.PostgresTypes, [Geo.PostGIS.Extension] ++ Ecto.Adapters.Postgres.extensions(), json: Poison)
and changed repo config like that.
config :lab_db, LabDb.Repo,
...
types: LabDb.PostgresTypes
I was then able to use specific type in my schema…
field :geom, Geo.Point
1 Like
Thanks for the reply!
I have added the type, and can now see that the extension is now being loaded, great!
But i’m still having some trouble defining the type.
field :bounding_box, Postgrex.Extensions.Box
# or
field :bounding_box, Postgrex.Box
# or
field :bounding_box, :box
is not working for me. All gives me the unknown or invalid type
error. Looking at the source code, it seems like there might not be a type defined?
1 Like
I’m not sure if you know it, but maybe you can look at how geo does work: https://github.com/bryanjos/geo
1 Like
Ecto types and postgrex extensions are two separate things. You need both.
2 Likes
Thanks for the reply!
So i need to define a box
type using the Ecto.Type
behaviour, making use of %Postgrex.Box{}
struct as my data structure?
1 Like
Yes, exactly. Sorry for making my last comment so brief.
To use a Postgres data type in Ecto that is not supported out of the box, you need two things:
- a postgrex extension - this is defined by the
Postgrex.Extension
behaviour. It is responsible for low-level concerns like encoding and decoding the data from the wire format when communicating directly with the database.
- an ecto type - this is defined by the
Ecto.Type
behaviour. It is responsible for higher-level features like casting and converting from application data format to raw database format (it might happen they are the same).
To use all of this, you need to define a custom postgrex type module using the custom extension and pass it as configuration to repo. This makes sure we can properly communicate with database. To use this type in the schema, the field
declaration needs to use the newly defined ecto type.
3 Likes
Thank you, that did the trick!
1 Like