luminus
luminus copied to clipboard
REPL instructions in migrations.html not working
To interactively create a new migration, https://luminusweb.com/docs/migrations.html tells you to do this:
(mount.core/start #'<app>.db.core/*db*)
(user/create-migration "add-users-table")
I can not get this to work. Fresh sample project created this week via lein new luminus foobar +postgres
, then adjusting :database-url
in dev-config.edn
, the db connection is known to work via lein run
.
This is what I get:
$ cd foobar
$ lein repl
user=> (mount.core/start #'foobar.db.core/*db*)
Execution error (ClassCastException) at foobar.db.core/eval13540$fn (core.clj:14).
class mount.core.DerefableState cannot be cast to class clojure.lang.IFn (mount.core.DerefableState is in unnamed module of loader clojure.lang.DynamicClassLoader @57540fd0; clojure.lang.IFn is in unnamed module of loader 'app')
### this is the error that confuses me
user=> (user/start)
2021-12-30 09:48:46,579 [nREPL-session-b1f4b012-2cd9-4cfa-87a4-e9f735c8e430] ERROR luminus.http-server - server failed to start on port: 3000
java.lang.RuntimeException: java.net.BindException: Address already in use
# this is not the problem, I know it's running, but I was playing around a bit
user=> (user/create-migration "foo" )
nil
### nothing happened
user=> (mount.core/start #'foobar.db.core/*db*)
{:started []}
### no more error
user=> (user/create-migration "change-something" )
nil
### still nothing happened
Also the line before the mount.start
reads:
(defstate ^:dynamic *db*
:start (conman/connect! {:jdbc-url (env :database-url)})
:stop (conman/disconnect! *db*))
whereas in the code it is currently
(defstate ^:dynamic *db*
:start (if-let [jdbc-url (env :database-url)]
(conman/connect! {:jdbc-url jdbc-url})
(do
(log/warn "database connection URL was not found, please set :database-url in your config, e.g: dev-config.edn")
*db*))
:stop (conman/disconnect! *db*))
and I can't tell if that's a simplified version by default, or if it has changed meanwhile, or something else
The problem is that your *db*
connection is not being started until (user/start)
is called. The address already in use error indicates that one of the resources defined using defstate
is trying to start on a port that's currently being used. If you're getting nil
output that should be fine, did you look if the file was created on the filesystem after running the command?
The problem is that your db connection is not being started until (user/start) is called.
Yes, that was my original point, the docs tell you to do X, but you need to to Y which isn't pointed out
The address already in use error indicates that one of the resources defined using defstate is trying to start on a port that's currently being used.
Yes, that is the only part that was unsurprising :)
If you're getting nil output that should be fine, did you look if the file was created on the filesystem after running the command?
The first one failed (user/create-migration "foo" )
no migrations generated.
The second one succeeded (user/create-migration "change-something" )
but only after the undocumented call to user/start
.
I'm mostly wondering if the version from the docs with just mount.core/start
can be made to work (again?), as described.
Just to be clear, when you run (mount.core/start #'<app>.db.core/*db*)
you replace <app>
with the actual namespace from your app?
Yes of course.
$ lein new luminus migtest +postgres
Generating a Luminus project.
$ cd migtest
$ vi dev-config.edn # for db credentials
$ find resources/migrations
resources/migrations
resources/migrations/20211230150621-add-users-table.down.sql
resources/migrations/20211230150621-add-users-table.up.sql
$ lein repl
nREPL server started on port 33943 on host 127.0.0.1 - nrepl://127.0.0.1:33943
REPL-y 0.5.1, nREPL 0.9.0
Clojure 1.10.3
OpenJDK 64-Bit Server VM 11.0.13+8-Ubuntu-0ubuntu1.18.04
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> (mount.core/start #'migtest.db.core/*db*)
Execution error (ClassCastException) at migtest.db.core/eval13540$fn (core.clj:14).
class mount.core.DerefableState cannot be cast to class clojure.lang.IFn (mount.core.DerefableState is in unnamed module of loader clojure.lang.DynamicClassLoader @57540fd0; clojure.lang.IFn is in unnamed module of loader 'app')
Oh I see your problem, the issue is that *db*
relies on env
to get the database url. Since nothing is started by default you'd need to run (mount.core/start #'migtest.config/env #'migtest.db.core/*db*)
. I'll update the docs to make a note of that.
Ah, that's the magic incantation that works. Thanks!
Reopen, misclick.