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
> 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.
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?
What do you mean by "`timestamp` class" exactly?
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 .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.
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.
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.
π« apologies for reawakening old demons haha
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.
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?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.
I'll remove the examples -- I can see how mentioning options that have nothing to do with next.jdbc is confusing.
thanks. agreed
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 π
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...