johnnyicon
How do I use the Postgres JSONB / Postgrex JSON extension?
Hi all,
I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.
I’m trying to use Postgres’ JSONB via the :map datatype.
Here’s my migration to add it to my table:
defmodule MyApp.Repo.Migrations.AddMapFieldToUser do
use Ecto.Migration
def change do
alter table(:users) do
add :data, :map
end
end
end
Here’s my schema:
defmodule MyApp.User do
use MyApp.Web, :model
use Coherence.Schema
schema "users" do
field :first_name, :string
field :last_name, :string
field :email, :string
field :data, :map
coherence_schema()
timestamps()
end
@doc """
Builds a changeset based on the `struct` and `params`.
"""
def changeset(struct, params \\ %{}) do
struct
|> cast(params, [:first_name, :last_name, :email] ++ coherence_fields)
|> unique_constraint(:email)
|> validate_required([:first_name, :last_name, :email])
|> validate_coherence(params)
end
end
I’ve been trying to set values into the data map using a changeset, but I haven’t had any luck. I’ve tried using both a JSON string and a map.
JSON string:
changeset = User.changeset(retrieved_user, %{data: "{test:'awesome'}"})
#Ecto.Changeset<action: nil, changes: %{}, errors: [],
data: #MyApp.User<>, valid?: true>
Map:
changeset = User.changeset(john, %{data: %{test: "awesome"}})
#Ecto.Changeset<action: nil, changes: %{}, errors: [],
data: #PodioBackup.User<>, valid?: true>
You’ll see that the changes map is empty.
Which leads me to believe that I am clearly missing something!
And I’m thinking maybe I need to add this JSON extension that many websites are referring to: postgrex/lib/postgrex/extensions/json.ex at master · elixir-ecto/postgrex · GitHub
How do I actually use that JSON extension? And, what am I doing wrong?
Thanks for the help in advance! ![]()
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #elixirconf-us
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 9 of 9 Posts!
alexgaribay
You’re missing a cast of
:datain your changeset.johnnyicon
Somehow I knew it was going to be something like that.
Thanks @alexgaribay. That was it!
nezzart
In this
shouldn’t the “data” be of type “jsonb” instead of “map”?
BrightEyesDavid
The first argument (
:data) inadd :data, :mapis the name of the table column. The type is the second argument (:map).Here’s the documentation for Ecto.Migration.add.
nezzart
yes, but my question is about “map” vs “jsonb”
david, your eyes are soooo green!
michalmuskala
They are equivalent when using postgres.
mapis an abstract type and each database adapter can choose the actual representation - for postgres it’sjsonb.Qqwy
So is a correct conclusion that using
:mapwould be preferable over using:json, to allow you to switch database adapters, if desired, later on?SoldierCoder
Is such a thought falling into this famous trap: “Premature optimization is the root of all evil!”? Or to put this another way, do you want your code to express what you are intending to happen right now? Or do you want your code to express what you MIGHT want it to do in the somewhat nebulous FUTURE?
“Why should you want to know?
Don’t you mind about the future
Don’t you try to think ahead
Save tomorrow for tomorrow
Think about today instead” – Jesus
Qqwy
No, I don’t think this is a case of premature optimization. Though I will admit that I don’t know exactly what my thoughts were when I wrote the last post in this topic in 2017, 8 years ago.
I would still consider that programming is a challenge of solving puzzles with often incomplete information. Doing as little optimization (regardless of what you’re optimizing for) as needed while keeping your project as flexible as possible for the future (within practical limits) is therefore often a great approach because you can make better choices in the future as you will have (more) complete information then.
In this case: it costs nothing (not in performance, not in memory and not in developer mental complexity) to use
:mapinstead of:jsonbif you want to store a hashmap with string keys in a Postgres column, whereas it does allow you to more easily switch over to a different database engine.I think that that can be considered roughly the opposite of premature optimization, especially of the kind that Dijkstra originally talked about.