This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-09-20
Channels
- # beginners (43)
- # boot (44)
- # chestnut (17)
- # cider (78)
- # cljs-dev (24)
- # cljsrn (16)
- # clojure (84)
- # clojure-dusseldorf (1)
- # clojure-italy (21)
- # clojure-losangeles (2)
- # clojure-russia (140)
- # clojure-sg (2)
- # clojure-spec (8)
- # clojure-uk (16)
- # clojurescript (23)
- # cursive (7)
- # datascript (1)
- # datomic (18)
- # docker (20)
- # ethereum (1)
- # fulcro (16)
- # garden (4)
- # graphql (27)
- # hoplon (9)
- # jobs (4)
- # luminus (34)
- # off-topic (6)
- # om (4)
- # onyx (35)
- # pedestal (3)
- # re-frame (24)
- # ring-swagger (15)
- # rum (6)
- # shadow-cljs (22)
- # spacemacs (8)
- # specter (22)
- # yada (7)
@misha @ivana дада. трушные кложуристы используют edn! ведь он принципиально мощнее json-а, и у него есть поддержка в куче либ и приложений!
да, мне на клиента результат жсоном отправлять. пока еще куча сложностей с его получением и формированием, но как решу их, буду смотреть чеширу и что там еще есть для ожсонивания.
Например из
SELECT
JC_CONTACT.CONTACT_ID,
JC_CONTACT.FIRST_NAME,
POSTS.POST_ID,
POSTS.TITLE,
COMMS.COMM_ID,
COMMS.COMM_TEXT,
CHILDRENS.CHILDREN_ID,
CHILDRENS.FIRST_NAME AS CHILDREN_NAME,
COMM_AUTHORS.CONTACT_ID AS AUTHOR_ID,
COMM_AUTHORS.FIRST_NAME AS AUTHOR_NAME
FROM JC_CONTACT
LEFT OUTER JOIN POSTS ON (JC_CONTACT.contact_id = POSTS.contact_id)
LEFT OUTER JOIN COMMS ON (POSTS.post_id = COMMS.post_id)
LEFT OUTER JOIN CHILDRENS ON (JC_CONTACT.contact_id = CHILDRENS.contact_id)
LEFT OUTER JOIN JC_CONTACT AS COMM_AUTHORS ON (COMM_AUTHORS.contact_id = COMMS.contact_id)
Но сейчас мне подсказали про несколько фичей SQL-я и я буду существенно переделывать и сам формат запросов и соответственно алгоритм их последующей обработки
ну да. форма ответа задается извне, в виде дерева (потом буду парсить ее из самого граф-куэль запроса), по ней строится текст запроса, получается, результат, обрабатывается моим велосипедом и получается такая иерархическая фигня, которую надо перегнать в жсон и отправить
да ладно. нельзя отдать {:contacts [ {id: 2, :name "Helga", :posts [{:id 4, :name "Post 4}, {...}]}, ... ] ?
запрос кстати кривой походу - кросспродукт всех комментраиев для контакста и всех его детей
@misha да там нету формата ответа. с точки зрения апи определяешь огрооомный такой ленвый объект
а потом делаешь запросы вида "дай мне все значения из филда :contacts, для которых вот такойт предикат true, и пожалуйста только вот такие и такие филды давай для них
т.е. эти вот ноды одинаковые - искусственные? (кто-то сам себе палок в колеса наставил)?
ну там не один объект, а несколько (типо REST endpoint), а уж их формат может быть любым. как сам сделаешь
что запрос кривой - не спорю, поэтому и курю сейчас sql, чтобы понять как писать прямые
@anjensan дык графкл - как раз про "запихать всё в 1 запрос", нет разве? (или ты про бд на бекэнде?)
@anjensan спасибо, а мне сказали что постгресс такой мощный, что можно все в 1 запрос - вот я и пытался сделать так
@misha ну с точки зрения API у тебя может быть один запрос. а уж транслируется он в несколько запросов в БД
не, я могу написать наивную реализацию, не вопрос! но тогда действительно будет 100500 запросов к базе на каждый входящий куэль запрос
@ivana важно, от этого зависит, как (rest api) запрос выглядит: выбор приоритета между "удобнее собирать запрос" и "удобнее использовать ответ"
в случае с постгрей - вполне себе решается 2мя запросами... SELECT user_id, comment_id FROM ..., & SELECT * FROM comments WHERE id IN $ids
вот чуваки сделали монстра http://join-monster.readthedocs.io/en/latest/ а вот какие запросы он рождает и какие результаты возвращает http://join-monster.herokuapp.com/graphql?query=%7B%0A%20%20user(id%3A%202)%20%7B%0A%20%20%20%20fullName%0A%20%20%20%20email%0A%20%20%20%20posts%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20body%0A%20%20%20%20%20%20createdAt%0A%20%20%20%20%20%20comments%20%7B%0A%20%20%20%20%20%20%20%20id%0A%20%20%20%20%20%20%20%20body%0A%20%20%20%20%20%20%20%20author%20%7B%0A%20%20%20%20%20%20%20%20%20%20id%0A%20%20%20%20%20%20%20%20%20%20fullName%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D
ну, прикол графкл в том, что ты трамбуешь всё в один апи запрос, который выглядит (структурно-ветвисто) как ответ который ты хочешь получить. Предпочтение там отдается тому, как выглядит ответ, который ты ожидаешь. Типа: то, что получил – сразу легко используешь, а чтоб собрать запрос – надо постараться.
юзать ответы апи геморно - это не моя беда. мне нужно запилить такое апи, а там пусть кто юзает тот и думает что спрашивать.
а у меня то возвращается все нормально, главное дерево правильное и структура, а лишнее убрать - ерунда
не может у тебя возвращаться все правильно как минимум потому, что запрос кривущий 😃
ну запрос кривой, да 🙂 поэтому и говорю, что сейчас думаю что требовать от sql, а потом уже как это обработать и зажсонить
ты выше написал про 2 запроса. тогда у меня будет 2 таблицы их результатов и я буду по ним обеим проходить? Или 1 таблица, а один подзапрос в WHERE или как там в постгрессе
@ivana конретно в твоем запрося я хз, ведь не понятно что нужно получить... но судя по всему нужно несколько запросов... вытащить список контактов. потом для них посты. для них комменты... отдельно детей (чтобы это не значило :))
конкретно в этом запросе я пытался впихнуть в одну таблицу ВСЮ иерархию: посты и дети персон, комменты к постам, авторы к комментам - такое вот дерево. И самое забавное, что мой велик прожевывает это, перебирает всю таблицу и строит правильное дерево. Хотя в таблице дофига строк из-за кросспродуктов будет в общем случае, да. Но мой велик пропускает дубли 🙂
там вы ответе ниже собственно заполненных данных есть структура иерархии, как часть этого дерева
пролема что так ты выгребаешь кучу дубликатов. например зачем тебе вытягивать текст всего поста для каждого коммента к нему ?
вообще ведь можно сделать SELECT * FROM JC_CONTACT, POSTS, COMMS, CHILDRENS, а потом все это дело запарсить в clojure. так тоже будет работать 😉
да, я уже напоролся на эти дубликаты. сейчас почитаю вдумчиво что ты написал, и попробую понять.
но мне нужны не все посты, дети, комменты и т.п.! А только те, которые приджойнятся к персонам а на персон условия потом пойдут
ну вот для этого нужно будет делать запросы вида SELECT * FROM POSTS WHERE id in (тут список, полученный на пред этапе из списка постов)
хм... ты пишешь точно то же, что делают ребята из джоин монстра по моей ссылке выше. А они (и ты) явно больше знают sql чем я
забей пока - для начала с азами/базой освойся, а потом уже в группировки и array_agg лезь
да и не поможет array_agg в деле вытаскивания / реконструирования древовидной структуры из реляционной БД
а я возлагал на нее надежды... ладно, пойдем по надежному пути, изучать sql и лепить несколько запросов
array_agg вообще - это надстройка постгреса. лучше выучить как это делать на "голом sql"
если честно, то я думал так - эти ребята, что сделали джойн-монстра, делали его не для постгресса, поэтому страдали от отсутствия аррай_эгг() и слепили как могли через несколько запросов 🙂 А мне надо для постгресса и я такой умный щас в один запрос все запишну, раз постгресс умеет много всего дополнительно 🙂
да, я читал про жсон_агг(), но это если тип колонки жсон. Хотя может там можно из всего при выполнении запроса жсон делать.... Спасибо, я посмотрю детальнее.
у меня снова все варианты в мозгах не умещаются 🙂 но еще раз спасибо вам, буду пробовать их все по очереди
но это по сути запихивание логики внутрь реляционки, что можно делать, если знаешь что делаешь
медленно... мне потом это на клиента слать - а те объемы на которых оно будет медленно, на клинта не пролезут имхо
@misha если у тебя есть дырка^W фича, то не значит что нужно с ней делать все подряд
мне кажется, что такой (хотя бы черновой) вариант - сильно нагляднее всех танцев с кастомными структурами данных и трансформациями. и может быть даже можно мимо кложи ответы отправлять
@misha нене. наглядность и простота сопровождения - это точно не про генерацию json на стороне постгри
@anjensan ну я не пользуюсь постгресом, и жсоны в sql базах не храню, потому не знаю зачем фича, и ради какого ююзкейса. Но не пользоваться фичей только потому что "непривычно" кому-то – такой себе аргумент
@ivana ну тогда при чем тут объемы. маленький объем помножить на дофига клиентво = загруженная база
как пример - запихунть полноценный джсон в 1 филд. построить индексы там полноценные и все такое
хз, распарсить глазами 20 строк sql проще будет, чем по 3 неймспейсам кастомные трансформации вычитывать
ну так и так запросы динамически генерить. только если ответы необработанные никак, то еще их обрабатывать больше после
вообще наверное ты прав да, с другой стороны в этом примере "генерить в кложе" отличается парой токенов row-to-json в этих селектах
всей инфы у меня нет, но сразу отбрасывать этот вариант именно в этом случае - я бы не стал
ну тут такое дело - генерить json (скажем более правильно - сериализовать. есть же еще bson, yaml, xml и прочее, юзеры апи могут предпочесть другой формат) на базе не прянято
1) это нагружает базу. БД обычно одна и трудно маштабируется, веб серверов много и легко накинуть еще => надо разгружать БД ка можно больше
2) фиг сделаешь пособработку (скажем формат для числа сделать, или там филд переименовать. или еще чего). пихать это в базу - усложняется дебаг и поддержка
3) структура базы должна соотв структуре твоей бизнес модели. это не всегда получается. но даже если получится... потом фиг поменяешь без жуткой боли
я понял, ты за разделение ответственности, чтобы база занималась только своим (условно) делом. Но если я осилю запилить другой вариант, без жсона в базе и с несколькими запросами...
и дальше переименовывать и тд. но да, мне "разные мелкие запросы" с этой точки зрения больше нравятся
ладно, если серьезно, есть 2 условно приемлемых варианта - несколько запросов и выгребание их в Кложе с заполнением нужной иерархической структуры, и вариант вешать логику компоновки жсонов на базу, так?
кстати эта, показываю ментору то что наработал на текущий момент (да-да, весь этот наркоманский алгоритм с кривыми запросами 🙂 ), может вы что подскажете по коду - как надо, как нельзя, за что руки оторвать, но только конструктивно - с указанием на что заменить и как правильно 🙂 https://github.com/Ivana-/GraphQL-Postgres-backend-test-1/blob/master/src/project_lein_1/core.clj
ждемс
кто-нибудь знает, lein для 9 починили?