lindem

lindem

Sqlite3: Generators need plural table names (was: workaround for the testing sandbox)

Hey fellow alchemists,

I was delighted to see that an sqlite3 adapter has indeed been developed since I tried phoenix and ecto last, so I decided to give it another try.

Sadly, with a phoenix liveview application, using the phx.gen.live generator, some generated tests always fail – specifically, the liveview tests deleting and updating items in a list always fail.

I tracked down the issue to the documented problem with the Ecto sandbox here.

I wish to just use the normal application repo with :memory: databases which can be destroyed and spun up relatively fast. I already found information regarding after_connect. I do not care enough about performance for this.

How do I define a new TestCase (like ConnCase) without the sandbox? The goal is to make the failing tests succeed and exclude them :slight_smile:

(If there was another way to make the generated tests run with sqlite3 with the sandbox enabled, I would be happy to be told how.)

The following creates a test project exhibiting the problem.

mix phx.new --database sqlite3 --live throwaway
cd throwaway
# create some entity in the db with associates liveviews
mix phx.gen.live Things Thing thing thingvalue:integer thingdescription:string
# copy routes into router.ex
mix test

Thanks for reading!

Because PostgreSQL always seems to be commented on: sqlite3 is going to be the production database, not some development crutch. I have been working with sqlite3 for almost 15 years, I am comfortable with it in this case. I know PostgreSQL well (and I love it too), but I do not wish to install, backup, and maintain another database cluster.

Marked As Solved

sodapopcan

sodapopcan

Ah ha, it’s because you didn’t pluralize your table name. It’s throwing off the generator.

I was able to reproduce with:

$ mix phx.gen.live Things Thing thing thingvalue:integer thingdescription:string

as in your example.

$ mix phx.gen.live Things Thing things thingvalue:integer thingdescription:string

works just fine.

Also Liked

christhekeele

christhekeele

Or something right, if you enjoy working on them as much as you indicate :grin:

At the end of the day, though, a HUGE % of B2B companies fall into 1 of 2 buckets:

  1. A domain-specific, context aware, edit-history-enabled pretty replacement for an Excel spreadsheet that powers an entire industry
  2. A domain-specific, context aware, edit-history-enabled pretty replacement for a single python script + an Excel spreadsheet that powers an entire industry

Find an industry with such a spreadsheet-driven workflow, and:

  • put the spreadsheets in a database
  • access it with CRUD
  • track modification history from form submissions
  • use domain knowledge to empower better visualizations

and you have a successful startup! For more advanced usecases, encode the script in a background job framework and you’re good to go.

This is clearly a very common need, so I am grateful that Phoenix (+ Oban) cover these usecases thoroughly, in case I end up working on such a project again, though I do avoid them as well.

warmwaffles

warmwaffles

The only generator I use day to day is mix ecto.gen.migration everything else is build as I need it. None of the generators produce even close to what we have for our admin panel and structuring. That has been my experience with generators (rails, django, phoenix, etc…) for the last 8 years.

christhekeele

christhekeele

At the end of the day, generators are just a way of copying somebody else’s code into your project. That will always require that your code style/conventions/structure match theirs to work out of the box.

I would rather copy my own project’s code with its own existing style/conventions/structure, so I essentially only use generators very early on in a project, to get the latest dependencies/configuration/wiring from the excellent phoenix generators, since phoenix and especially liveview is still iterating fast (though we are due for a liveview 1.0 soon so I expect this to slow down dramatically).

By the time I have a roughly working initial project setup, I’ve modified these generated defaults and conventions to suit my needs enough that I can copy my own code as a “template”. I pretty much only use the ecto migration generator from there on out, mostly so that I don’t have to generate my own timestamps for migration names. (Even then I write most migrations in pure SQL, so completely replace the migration DSL inserted into those files.)

One reason I ditch the generators very early on is because I never actually want to use Phoenix’s namespacing/context conventions, so pretty much any initial codebase I write quickly strays from their conventions, you may get more milage if you follow them.

warmwaffles

warmwaffles

I do to, but two problems you will face doing this.

  1. Right now exqlite is dependent on :db_connection which makes :memory: a bit difficult to work with. There is discussion to remove it as a dependency. Replace DirtyNIF execution model with a different mechanism · Issue #192 · elixir-sqlite/exqlite · GitHub
  2. Every time you check out a new connection, you will need to run the migrations from start to finish OR load the database structure every time you check it out. Just something to keep in mind if you want to use the :memory: route.

I definitely have a dream of using :memory: for testing in a massively parallel way. The first step to accomplishing this is to remove the dependency on :db_connection and implement our own pooling mechanism or just live with one genserver. The second step is to make that spin up time be as fast as possible when using :memory: and benchmark that against using the sandbox.

sodapopcan

sodapopcan

If you want to use the generators you could always generate with a plural name then edit the migration and the schema to be singular.

…or open an issue in Phoenix to make singular table names work! Not sure it would be accepted but you can always try :slight_smile:

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
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
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
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 45766 226
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

We're in Beta

About us Mission Statement