sql

Santiago 2024-05-08T12:04:15.697279Z

I'm trying to replace postgres with sqlite (motivation is "I want to try it out" https://clojurians.slack.com/archives/C1Q164V29/p1714036240189029). Columns stored in the db as "TIMESTAMP" are converted to strings when using get-by-id (I'm assuming the problem is not this function). I tried invoking (read-as-instant) when the app launches, but spec still complains the timestamps are strings. Reading from the DB when using postgres was perfect TIMESTAMP->instant conversion. What could I be missing? e.g. I'm not sure 1) if I need read-as-instant at all

p-himik 2024-05-08T12:19:31.523099Z

> SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in https://www.sqlite.org/lang_datefunc.html of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values The data isn't converted to strings, the data is strings.

Santiago 2024-05-08T14:42:12.323999Z

huh so the timestamp class is a lie? πŸ₯Ή so update-in and parse the timestamp or using a builder fn is what people actually do?

p-himik 2024-05-08T14:46:47.061239Z

What do you mean by "`timestamp` class" exactly?

Santiago 2024-05-08T15:06:55.288489Z

I created the table like so:

created_at timestamp default current_timestamp
and when I open the database in a DB client the column class is timestamp .

Santiago 2024-05-08T15:15:22.048919Z

reading more about it confirms there is some trickery πŸ˜„ the db converts the values into strings before writing it into the db. The timestamp and datetime classes just make it look nice.

p-himik 2024-05-08T15:19:02.551569Z

That timestamp is a lie, yes: https://www.sqlite.org/datatype3.html#affinity_name_examples Note that the matching is a bit nuts - if the type name ends with 'int', it will be an integer, even if the full name is floating point. More than a decade ago, I was evaluating SQLite for some personal projects. Immediately decided against it for the foreseeable future because of things like this. :) There were others though, quite a few, but I wouldn't be able to recall.

p-himik 2024-05-08T15:20:53.132039Z

Ah yes, this is a valid statement in SQLite: create table t (x sdfvsdfvsdfv);. Too lazy to check at this point because the long forgotten dislike of SQLite starts to reappear, but I assume x is actually TEXT.

Santiago 2024-05-08T15:21:40.092259Z

🫠 apologies for reawakening old demons haha

2024-05-08T18:40:26.965189Z

Honestly, I was in the same boat with SQLite last year but it’s got a lot of quirks (some of which are https://andersmurphy.com/2023/07/16/clojure-sqlite-application-defined-sql-functions-with-jdbc.html, but also some that are a nightmare). I’ve found https://github.com/juji-io/datalevin a much better fit for the places I’d normally use SQLite with Clojure. The datalog/triple store approach to relational databases is really cool once you get the hang of it.

Felipe 2024-05-08T18:39:41.000889Z

I want to run EXPLAIN / EXPLAIN ANALYZE on a query. next.jdbc's docs say

* Keyword options no longer end in `?` -- for consistency (in `clojure.java.jdbc`, some flag options ended in `?` and some did not; also some options that ended in `?` accepted non-`Boolean` values, e.g., `:as-arrays?` and `:explain?`),
neither {:explain? "EXPLAIN ANALYZE"} nor {:explain "EXPLAIN ANALYZE"} seem to be EXPLAINing things and there are no clj code results for explain when using github search. is this still a valid option for next.jdbc?

seancorfield 2024-05-08T18:45:31.801499Z

That paragraph is giving examples of inconsistencies in options for clojure.java.jdbc. It's not meant to imply any of those options exist in next.jdbc.

πŸ‘ 1
seancorfield 2024-05-08T18:46:16.296269Z

I'll remove the examples -- I can see how mentioning options that have nothing to do with next.jdbc is confusing.

Felipe 2024-05-08T18:54:20.666889Z

thanks. agreed

Felipe 2024-05-08T18:55:20.045609Z

seems to be quite simple to do: (defn explain [sql-params] (update sql-params 0 #(str "EXPLAIN ANALYZE " %))) just wanted to know if there was a built-in helper πŸ™‚

seancorfield 2024-05-08T19:03:09.411559Z

Yeah, I think it's better to handle it explicitly. Adding it to c.j.j was a mistake, really, since it also needed an :explain-fn option to do anything useful with the result. It was also pretty weirdly DB-specific so having it in an generic JDBC library was... odd...

πŸ‘ 2