honeysql

sheluchin 2024-05-13T16:48:53.171539Z

Anyone hooked up HoneySQL for use in a https://docs.getdbt.com/ project? I'm thinking something along the lines of writing the models in HoneySQL, compiling them into DBT models as SQL and then letting DBT do the rest. Shouldn't be hard, I'm just wondering if anyone has something going.

p-himik 2024-05-13T16:50:58.855019Z

If it's regular SQL then there are no show-stoppers. There's no need for any prior art here, you can simply rely on HoneySQL and its docs.

sheluchin 2024-05-13T16:54:00.227759Z

It's almost regular SQL, just with Jinja templating tags involved. Would need to register a HoneySQL fn to create {{ ref('model_name') }} tags and similar. Besides that there are a bunch of DBT CLI commands like compile, run, etc. that expect SQL files in certain places. I'd like to have it so I only have to touch HoneySQL files and the rest happens seamlessly.

2024-05-13T20:13:18.472399Z

i'm trying to get the :join https://cljdoc.org/d/com.github.seancorfield/honeysql/2.6.1126/doc/getting-started/sql-special-syntax-#join working but i'm struggling a bit. i want

SELECT *
FROM foo
LEFT JOIN (populations pm INNER JOIN customers pc ON pm.id = pc.id AND pm.other_id = pc.other_id)
ON foo.fk_id = pm.id
I have
(-> (hh/select :*)
    (hh/from :foo)
    (hh/left-join [[:join [:populations :pm]
                    (hh/join [:customers :pc]
                             [:and [:= :pm.id :pc.id]
                              [:= :pm.other_id :pc.other_id]])]]
                  [:and [:= :foo.fk_id :pm.id]
                   [:= :foo.other_fk_id :pm.other_id]])
    (sqlv2/format)
    (println))
but this produces
[SELECT * FROM "foo" LEFT JOIN JOIN(POPULATIONS("pm"), (INNER JOIN "customers" AS "pc" ON ("pm"."id" = "pc"."id") AND ("pm"."other_id" = "pc"."other_id"))) ON ("foo"."fk_id" = "pm"."id") AND ("foo"."other_fk_id" = "pm"."other_id")]

✅ 1
2024-05-13T20:18:10.757859Z

I can't seem to get the :join call right such that it correctly nests the initial table and alias

2024-05-13T20:19:34.213469Z

huh, it seems that even the example doesn't work for me:

(sqlv2/format {:join [[[:join :tbl1 {:left-join [:tbl2 [:using :id]]}]]]})
; ["INNER JOIN JOIN(\"tbl1\", (LEFT JOIN \"tbl2\" USING (\"id\")))"]

2024-05-13T20:19:48.677519Z

is this determined by a dialect setting? we're using:

(sqlv2/set-dialect! :ansi :quoted true)

p-himik 2024-05-13T20:20:32.890099Z

Are you using the most recent version of HoneySQL?

2024-05-13T20:21:27.438229Z

good call, we're using 2.4.1011. lemme update and see if that fixes it

2024-05-13T20:22:44.567489Z

https://github.com/seancorfield/honeysql/releases/tag/v2.4.1026 there we go, i was one version behind for this

2024-05-13T20:22:50.678949Z

thanks, should have checked the version first

p-himik 2024-05-13T20:28:00.450349Z

Can't quite achieve what you want because I can only get populations(pm) and not populations pm or populations as pm.

👍 1
2024-05-13T20:28:33.839969Z

i can work around that, i'm just glad to get the nested join working

p-himik 2024-05-13T20:29:03.590539Z

How would you work around that?

2024-05-13T20:29:33.764909Z

just not use an alias in this case

p-himik 2024-05-13T20:29:49.354359Z

Ah. :)

p-himik 2024-05-13T20:31:54.587089Z

An alternative is to use :raw. But seems like it's a limitation of HoneySQL.

2024-05-13T20:34:44.968229Z

[:join [:raw "populations pm"] ...] does the trick

2024-05-13T20:34:55.991339Z

not ideal but much nicer than no aliases lol

p-himik 2024-05-13T20:38:21.240639Z

Created https://github.com/seancorfield/honeysql/issues/529

🎉 1
seancorfield 2024-05-13T22:29:32.185159Z

I considered it a bug that [:populations :pm] did not work to create an alias. Fixed on develop and a new snapshot will be available shortly. I'll probably cut a new release this weekend.

🎉 1
2024-05-13T20:37:24.845619Z

2024-05-13T22:27:37.283149Z