Programming Ecto (Pragprog)

Just wanted to stated that I enjoyed this book a lot. :grinning:
Thank you @ericmj and @darinwilson for putting this together.

Favourite aspects of the book.

• I liked that Part I - Ecto Fundamentals encourages the reader to test and play with all the key features of Ecto. It made the book easy to jump into and kept me focused on first playing and testing things out. The ability to “play” is a key feature for learning.

• A lot of knowledge about Querying, Changesets, Schemas before even dealing with migrations. Thinking about structure, tables, columns and table joins later on in the book was a good move.

• Appreciate the ability to always reset the test data in the demo app.

Part II - Optimizing IEx for Ecto. I had no clue you can do that. Huge time saving tip for customizing IEx.

• Embedded schemas. Did not realize some of the things you can do with embedded schemas.

• Performing upserts with :on_conflict chapter. This now makes a lot of sense.

Whether your a beginner or an expert in Elixir this book is easy and fun to go through. I have already started refactoring some code on a current project with the new knowledge I have on Ecto.

Highly recommend the book. :+1:

5 Likes

Thanks for the nice feedback @neuone - I’m glad you found the book helpful!

1 Like

When running snippets in the programming ecto code project, I keep getting a strange error message:

iex(1)> Repo.insert(%Genre{name: "speed polka"})
# {:ok, %MusicDB.Genre{...}}

iex(2)> Repo.insert(%Genre{name: "speed polka"})
# ** (MatchError) no match of right hand side value: []

If I run code via the playground module, then I get the actual error message.

In a different project I get proper ecto error messages when in IEX shell. Can anyone suggest what might be going on?

@darinwilson any thoughts on this ? :point_up:

To clarify, all DB level errors are returned as this:

** (MatchError) no match of right hand side value: []

So the first insert works fine, but the second fails a unique constraint but returns an unusual error message.

To reiterate, any failing operation that I run in the playground, it correctly returns the standard error message.


Another example:

iex(5)> Repo.insert(%MusicDB.Artist{})
** (MatchError) no match of right hand side value: []
# 13:01:08.566 [debug] QUERY ERROR db=0.7ms queue=3.1ms
# INSERT INTO "artists" ("inserted_at","updated_at") VALUES ($1,$2) RETURNING "id" [~N[2020-08-09 11:01:08], ~N[2020-08-09 11:01:08]]

Hi @jmurphyweb :wave:

What version of Elixir/Erlang are you using? I tried the example using Elixir 1.9 and Erlang 21.3.7 and I got the expected behavior in IEx, i.e. it showed the full error message:

iex(3)> Repo.insert(%Genre{name: "speed polka"})

09:17:52.517 [debug] QUERY ERROR db=2.9ms queue=0.5ms
INSERT INTO "genres" ("name","inserted_at","updated_at") VALUES ($1,$2,$3) RETURNING "id" ["speed polka", ~N[2020-08-10 16:17:52], ~N[2020-08-10 16:17:52]]
** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * genres_name_index (unique_constraint)
...

If you’re on Elixir 1.10, maybe something changed in IEx that’s triggering different behavior. Or is it possible that you have a global .iex.exs that’s modifying the behavior? I’m a little stumped, so I’m just guessing here… :confused:

2 Likes

I dropped down to elixir 1.9 and ran it but had the same result.
I’ve never set up a global .iex.exs file.

I’ll try a fresh install of the project and re-run it.


Fresh install works fine. No idea what I did on the old one… Thanks @darinwilson


Strangely enough when I moved the project back into my programming-ecto subdirectory the problem re-occurred. Moving the project back out and all is well again. I can’t understand why that happens but happy to ignore now it’s working again :+1:

Huh - that’s really strange.

Well, I guess it’s not quite “mystery solved” but I’m glad it’s at least “mystery REsolved” :smile:

1 Like

Encounter the problem when I run the seed.exs

Interestingly, it looks like the data were loaded few steps before the seed (probably, automatically when I invoke ecto create?)
So I’m able to count the loaded records from console

iex(1)> MusicDB.Repo.aggregate("artists", :count, :id)
22:56:04.664 [debug] QUERY OK source="artists" db=6.0ms decode=4.0ms queue=7.8ms idle=449.8ms
SELECT count(a0."id") FROM "artists" AS a0 []
3

Hence the message signals I’m inserting there duplicates? Or what?


$ mix run priv/repo/seeds.exs 
warning: use Mix.Config is deprecated. Use the Config module instead
  config/config.exs:11

warning: use Mix.Config is deprecated. Use the Config module instead
  config/dev.exs:9


22:31:28.937 [debug] QUERY ERROR db=24.7ms queue=4.3ms idle=10.2ms
INSERT INTO "genres" ("name","wiki_tag","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" ["jazz", "Jazz", ~N[2022-11-17 19:31:28], ~N[2022-11-17 19:31:28]]
** (Ecto.ConstraintError) constraint error when attempting to insert struct:

    * genres_name_index (unique_constraint)

If you would like to stop this constraint violation from raising an
exception and instead add it as an error to your changeset, please
call `unique_constraint/3` on your changeset with the constraint
`:name` as an option.

The changeset has not defined any constraint.

    (ecto 3.9.1) lib/ecto/repo/schema.ex:795: anonymous fn/4 in Ecto.Repo.Schema.constraints_to_errors/3
    (elixir 1.14.2) lib/enum.ex:1658: Enum."-map/2-lists^map/1-0-"/2
    (ecto 3.9.1) lib/ecto/repo/schema.ex:780: Ecto.Repo.Schema.constraints_to_errors/3
    (ecto 3.9.1) lib/ecto/repo/schema.ex:761: Ecto.Repo.Schema.apply/4
    (ecto 3.9.1) lib/ecto/repo/schema.ex:369: anonymous fn/15 in Ecto.Repo.Schema.do_insert/4
    (ecto 3.9.1) lib/ecto/repo/schema.ex:265: Ecto.Repo.Schema.insert!/4
    priv/repo/seeds.exs:12: (file)

For anyone still following this thread - how relevant is the book now that it’s 4+ years past release? Are many parts outdated or is it still a good reference for someone new to Ecto?

The official docs are good and I can pick up the basics, but would be interested in the advanced parts, how to use Ecto in a real-world app - more or less in line with what I’ve read from the book’s table of contents. Thanks!

1 Like

Yes, the book is most definitely relevant today. I still read some parts from time to time. Ecto hasn’t changed much, new features have been added but that’s about it.

5 Likes

I do think Programming Ecto is still relevant today but you might want to checkout the Dashbit’s book “The Little Ecto Cookbook” which has some advanced topics and it is relevant for Ecto 3.10 and later as the author says… as a bonus, it’s free.

You can find the book here: The Little Ecto Cookbook - Dashbit ebooks

Best regards,

2 Likes