michaelwa

michaelwa

ExAws.Dynamo.Encoder and Ecto.Schema do not work together

My mix.exs dependencies (partial list):
{:ex_aws, “~> 2.1”},
{:ex_aws_dynamo, “~> 4.0”},
{:hackney, “~> 1.9”},
{:configparser_ex, “~> 4.0”}I created an Ecto.Schema:

I can create dyanmo tables, insert, update, and delete records just fine as long as the data records are derived from generic structs.

However, when I create an Ecto.Schema

defmodule IntandemWww.Users.User do
use Ecto.Schema
import Ecto.Changeset

@derive [ExAws.Dynamo.Encodable]

schema “users” do
field :name, :string, virtual: true
field :first_name, :string
field :middle_name, :string
field :last_name, :string
field :condition, :string
field :email, :string
field :phone, :string
field :status, :string
field :mentor, :string
field :enrollment_date, :string

timestamps()

end
end

Instance looks like this (note the “meta” attribute):

%Users.User{
meta: #Ecto.Schema.Metadata<:built, “users”>,
id: nil,
name: nil,
first_name: nil,
middle_name: nil,
last_name: nil,
condition: nil,
email: nil,
phone: nil,
status: nil,
mentor: nil,
enrollment_date: nil,
inserted_at: nil,
updated_at: nil
}

Then when I try to Encode it (with some actual data set though):

Dynamo.Encoder.encode!(new_user)

I get the following error:

** (Protocol.UndefinedError) protocol ExAws.Dynamo.Encodable not implemented for #Ecto.Schema.Metadata<:built, “users”> of type Ecto.Schema.Metadata (a struct). This protocol is implemented for the following type(s): Atom, BitString, Float, HashDict, Users.User, Integer, List, Map, MapSet, User
(ex_aws_dynamo 4.2.1) lib/ex_aws/dynamo/encodable.ex:1: ExAws.Dynamo.Encodable.impl_for!/1
(ex_aws_dynamo 4.2.1) lib/ex_aws/dynamo/encodable.ex:5: ExAws.Dynamo.Encodable.encode/2
(ex_aws_dynamo 4.2.1) lib/ex_aws/dynamo/encodable.ex:87: anonymous fn/2 in ExAws.Dynamo.Encodable.Map.do_encode/1
(stdlib 4.0.1) maps.erl:411: :maps.fold_1/3
(ex_aws_dynamo 4.2.1) lib/ex_aws/dynamo/encodable.ex:64: ExAws.Dynamo.Encodable.Map.encode/2

I looked through the encoder.ex in the ex_aws_dynamo dependency and the “meta” field is obviously not accounted for during encoding.

Is anyone using Ecto.Schema with Dynamo and if so how? Is this an oversight or were they not meant to ever work together?

I do not see any usage of the “options” that are passed to “encode” functions. Would a valid solution be to add “ignore_fields” as an array of fields to skip over?

Most Liked

michaelwa

michaelwa

Thank you!! Thank you! This gets me moving forward again!!

This worked!

@derive {ExAws.Dynamo.Encodable, only: [:name, :first_name, :middle_name, :last_name, :condition, :email, :phone, :status, :mentor, :enrollment_date, :inserted_at, :updated_at]}

I note that right below:

def do_encode(map, only: only) do

That there is an “except”:

def do_encode(map, except: except) do

I tried the three variants below. They all compile but no happiness!

@derive {ExAws.Dynamo.Encodable, except: [Ecto.Schema.Metadata]}
@derive {ExAws.Dynamo.Encodable, except: [:__meta__]}
@derive {ExAws.Dynamo.Encodable, except: ["__meta__"]}

I also see in the Ecto.Schema module the following:

Module.put_attribute(__MODULE__, :ecto_struct_fields, {:__meta__, meta})

So I would have guessed the :atom version should have worked.

al2o3cr

al2o3cr

(Note: I edited your post to use ``` to preserve code-formatting, underscores etc)

The encode function accepts an except option, but that’s distinct from the code generated when you say @derive {ExAws.Dynamo.Encodable, etc etc etc}.

https://github.com/ex-aws/ex_aws_dynamo/blob/2e523c9efb81e41c13da8b62859296b5b60d3991/lib/ex_aws/dynamo/encodable.ex#L38-L52

What you want would be something like:

extractor =
  cond
    only = options[:only] ->
      quote(do: Map.take(struct, unquote(only)))

    except = options[:except] ->
      quote(do: :maps.without(unquote(except), struct))

    true ->
      quote(do: :maps.remove(:__struct__, struct))

and then you could say:

# NOTE TO FUTURE GOOGLERS: THIS LINE REQUIRES THE CHANGE ABOVE!
@derive {ExAws.Dynamo.Encodable, except: [:__struct__, :__meta__]}

This could make a good PR to ExAws.Dynamo, if you added some tests. Maybe :except should automatically add :__struct__ :thinking:

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39467 209
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 48342 226
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement