clojure-russia

Работа и релокейт: #jobs-rus | #clojure-russia-offtop Телеграм-чат https://t.me/clojure_ru
anjensan 2017-09-20T09:11:19.000185Z

@misha @ivana дада. трушные кложуристы используют edn! ведь он принципиально мощнее json-а, и у него есть поддержка в куче либ и приложений!

misha 2017-09-20T09:26:30.000071Z

задача выше была вроде под graphql подвязана, наверное для этого жсон

2017-09-20T10:13:47.000267Z

да, мне на клиента результат жсоном отправлять. пока еще куча сложностей с его получением и формированием, но как решу их, буду смотреть чеширу и что там еще есть для ожсонивания.

misha 2017-09-20T11:45:07.000435Z

а покажи ка пример из чего плоского во что ветвистое тебе нужно переложить?

misha 2017-09-20T11:45:17.000515Z

а то скучно что-то :opieop:

2017-09-20T11:48:37.000125Z

Например из

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)

2017-09-20T11:50:36.000065Z

Но сейчас мне подсказали про несколько фичей SQL-я и я буду существенно переделывать и сам формат запросов и соответственно алгоритм их последующей обработки

misha 2017-09-20T12:17:05.000277Z

это графкл такой формы ответ хочет?

2017-09-20T12:20:17.000516Z

ну да. форма ответа задается извне, в виде дерева (потом буду парсить ее из самого граф-куэль запроса), по ней строится текст запроса, получается, результат, обрабатывается моим велосипедом и получается такая иерархическая фигня, которую надо перегнать в жсон и отправить

anjensan 2017-09-20T12:26:29.000121Z

да ладно. нельзя отдать {:contacts [ {id: 2, :name "Helga", :posts [{:id 4, :name "Post 4}, {...}]}, ... ] ?

anjensan 2017-09-20T12:27:19.000341Z

запрос кстати кривой походу - кросспродукт всех комментраиев для контакста и всех его детей

misha 2017-09-20T12:27:52.000149Z

я графкл не знаю, но осуждаю считаю, что датомиковские запрос/ответ сильно чётче :opieop:

anjensan 2017-09-20T12:27:54.000210Z

врядли это то, что предполагалось (или тут наркоманская логика, не знаю)

anjensan 2017-09-20T12:28:26.000132Z

@misha да там нету формата ответа. с точки зрения апи определяешь огрооомный такой ленвый объект

anjensan 2017-09-20T12:29:00.000161Z

а потом делаешь запросы вида "дай мне все значения из филда :contacts, для которых вот такойт предикат true, и пожалуйста только вот такие и такие филды давай для них

misha 2017-09-20T12:29:36.000194Z

т.е. эти вот ноды одинаковые - искусственные? (кто-то сам себе палок в колеса наставил)?

anjensan 2017-09-20T12:29:44.000010Z

ну там не один объект, а несколько (типо REST endpoint), а уж их формат может быть любым. как сам сделаешь

2017-09-20T12:31:06.000086Z

что запрос кривой - не спорю, поэтому и курю сейчас sql, чтобы понять как писать прямые

misha 2017-09-20T12:31:15.000459Z

может пацанам проще такое парсить на юае, кто знает

anjensan 2017-09-20T12:31:16.000291Z

я обычно такое называю наркоманией, но вообще да, искусственные 😃

misha 2017-09-20T12:31:51.000335Z

@ivana на сколько я знаю, в графкл - запрос повторяет форму ответа, а не наоборот

anjensan 2017-09-20T12:31:54.000316Z

@ivana правило N0 - не пытатьс все запихнуть в 1 запрос

✅ 2
2017-09-20T12:31:58.000293Z

а насчет что отдать в каком формате - когда решу с sql, буду уже о форматах думать

misha 2017-09-20T12:32:24.000126Z

@anjensan дык графкл - как раз про "запихать всё в 1 запрос", нет разве? (или ты про бд на бекэнде?)

anjensan 2017-09-20T12:32:26.000303Z

ну если пацанам такое на ui проще писать - знач на ui уже побывали наркоманы 🙂

2017-09-20T12:32:42.000151Z

@anjensan спасибо, а мне сказали что постгресс такой мощный, что можно все в 1 запрос - вот я и пытался сделать так

anjensan 2017-09-20T12:33:09.000460Z

@misha ну с точки зрения API у тебя может быть один запрос. а уж транслируется он в несколько запросов в БД

anjensan 2017-09-20T12:33:19.000323Z

по краней мере если у тебя БД реляционная

2017-09-20T12:33:30.000083Z

@malch что там повторяет чью форму - не важно. или я тебя не так понял

malch 2017-09-20T12:33:46.000145Z

ну почти я 😃

misha 2017-09-20T12:33:46.000316Z

а, если про бд, то "да", но как жеж тогда N+1 проблема? база-то мутабельная :kappa:

2017-09-20T12:34:18.000284Z

не, я могу написать наивную реализацию, не вопрос! но тогда действительно будет 100500 запросов к базе на каждый входящий куэль запрос

anjensan 2017-09-20T12:34:22.000149Z

транзакции

anjensan 2017-09-20T12:34:52.000111Z

и проблема N+1 это чутка про другое

misha 2017-09-20T12:35:19.000481Z

@ivana важно, от этого зависит, как (rest api) запрос выглядит: выбор приоритета между "удобнее собирать запрос" и "удобнее использовать ответ"

2017-09-20T12:35:40.000130Z

не понял, можешь раскрыть мысль?

anjensan 2017-09-20T12:35:43.000158Z

в случае с постгрей - вполне себе решается 2мя запросами... SELECT user_id, comment_id FROM ..., & SELECT * FROM comments WHERE id IN $ids

2017-09-20T12:36:10.000213Z

щас кину ссылку про то что ты пишешь, похоже...

anjensan 2017-09-20T12:36:43.000227Z

@ivana тебе пытаются намекнуть, что юзать такие ответы от апи очень и очень геморно

misha 2017-09-20T12:38:28.000453Z

ну, прикол графкл в том, что ты трамбуешь всё в один апи запрос, который выглядит (структурно-ветвисто) как ответ который ты хочешь получить. Предпочтение там отдается тому, как выглядит ответ, который ты ожидаешь. Типа: то, что получил – сразу легко используешь, а чтоб собрать запрос – надо постараться.

2017-09-20T12:38:44.000066Z

юзать ответы апи геморно - это не моя беда. мне нужно запилить такое апи, а там пусть кто юзает тот и думает что спрашивать.

anjensan 2017-09-20T12:38:57.000139Z

@ivana норм ответы он возвращает. а у тебя какие монстры

misha 2017-09-20T12:39:15.000010Z

хз тогда : )

2017-09-20T12:39:23.000076Z

я ссылку дал больше про 2 текста sql запросов посмотреть

2017-09-20T12:39:49.000313Z

а у меня то возвращается все нормально, главное дерево правильное и структура, а лишнее убрать - ерунда

misha 2017-09-20T12:40:16.000393Z

¯\(ツ)

anjensan 2017-09-20T12:40:22.000311Z

не может у тебя возвращаться все правильно как минимум потому, что запрос кривущий 😃

anjensan 2017-09-20T12:40:26.000365Z

не надо тут рассказывать

misha 2017-09-20T12:40:44.000209Z

:d:

2017-09-20T12:41:13.000355Z

ну запрос кривой, да 🙂 поэтому и говорю, что сейчас думаю что требовать от sql, а потом уже как это обработать и зажсонить

2017-09-20T12:42:22.000089Z

ты выше написал про 2 запроса. тогда у меня будет 2 таблицы их результатов и я буду по ним обеим проходить? Или 1 таблица, а один подзапрос в WHERE или как там в постгрессе

2017-09-20T12:42:43.000209Z

Не смейтесь, я с sql не работал

anjensan 2017-09-20T12:44:10.000440Z

https://en.wikipedia.org/wiki/Relational_algebra

anjensan 2017-09-20T12:44:17.000037Z

для затравки

anjensan 2017-09-20T12:45:02.000201Z

https://habrahabr.ru/post/145381/

anjensan 2017-09-20T12:45:14.000308Z

а уж потом можно пробовать запросы писать =\

2017-09-20T12:45:48.000011Z

ох, спасибо, Айболит! сколько всего осиливать... 🙂 Но выбора нет 🙂

misha 2017-09-20T12:46:58.000046Z

ой, хабр, чур-чур!

anjensan 2017-09-20T12:49:01.000063Z

рандомная ссылка на русском из гугля 🙂

misha 2017-09-20T12:49:08.000086Z

:eew:

anjensan 2017-09-20T12:59:04.000338Z

@ivana конретно в твоем запрося я хз, ведь не понятно что нужно получить... но судя по всему нужно несколько запросов... вытащить список контактов. потом для них посты. для них комменты... отдельно детей (чтобы это не значило :))

2017-09-20T13:01:25.000013Z

конкретно в этом запросе я пытался впихнуть в одну таблицу ВСЮ иерархию: посты и дети персон, комменты к постам, авторы к комментам - такое вот дерево. И самое забавное, что мой велик прожевывает это, перебирает всю таблицу и строит правильное дерево. Хотя в таблице дофига строк из-за кросспродуктов будет в общем случае, да. Но мой велик пропускает дубли 🙂

2017-09-20T13:02:11.000370Z

там вы ответе ниже собственно заполненных данных есть структура иерархии, как часть этого дерева

anjensan 2017-09-20T13:02:40.000078Z

пролема что так ты выгребаешь кучу дубликатов. например зачем тебе вытягивать текст всего поста для каждого коммента к нему ?

anjensan 2017-09-20T13:03:32.000357Z

вообще ведь можно сделать SELECT * FROM JC_CONTACT, POSTS, COMMS, CHILDRENS, а потом все это дело запарсить в clojure. так тоже будет работать 😉

2017-09-20T13:04:06.000241Z

да, я уже напоролся на эти дубликаты. сейчас почитаю вдумчиво что ты написал, и попробую понять.

2017-09-20T13:05:05.000091Z

но мне нужны не все посты, дети, комменты и т.п.! А только те, которые приджойнятся к персонам а на персон условия потом пойдут

anjensan 2017-09-20T13:06:17.000362Z

ну вот для этого нужно будет делать запросы вида SELECT * FROM POSTS WHERE id in (тут список, полученный на пред этапе из списка постов)

2017-09-20T13:06:36.000476Z

мне тут еще подсказали такую штуку постгресса как array_agg, буду думать чем полезна

anjensan 2017-09-20T13:06:50.000070Z

а потом в clojure из всего этого (несколько селектов) собирать дерево

2017-09-20T13:07:42.000311Z

хм... ты пишешь точно то же, что делают ребята из джоин монстра по моей ссылке выше. А они (и ты) явно больше знают sql чем я

anjensan 2017-09-20T13:07:50.000551Z

забей пока - для начала с азами/базой освойся, а потом уже в группировки и array_agg лезь

anjensan 2017-09-20T13:08:48.000420Z

да и не поможет array_agg в деле вытаскивания / реконструирования древовидной структуры из реляционной БД

2017-09-20T13:09:38.000041Z

а я возлагал на нее надежды... ладно, пойдем по надежному пути, изучать sql и лепить несколько запросов

anjensan 2017-09-20T13:10:26.000316Z

array_agg вообще - это надстройка постгреса. лучше выучить как это делать на "голом sql"

2017-09-20T13:12:19.000077Z

если честно, то я думал так - эти ребята, что сделали джойн-монстра, делали его не для постгресса, поэтому страдали от отсутствия аррай_эгг() и слепили как могли через несколько запросов 🙂 А мне надо для постгресса и я такой умный щас в один запрос все запишну, раз постгресс умеет много всего дополнительно 🙂

2017-09-20T13:17:06.000676Z

да, я читал про жсон_агг(), но это если тип колонки жсон. Хотя может там можно из всего при выполнении запроса жсон делать.... Спасибо, я посмотрю детальнее.

anjensan 2017-09-20T13:17:08.000387Z

@misha зачем ты человека смущаешь 🙂

misha 2017-09-20T13:17:58.000499Z

row_to_json же! :kappa:

✅ 1
anjensan 2017-09-20T13:19:17.000292Z

@ivana не делай так, пожалуйста 🙂

2017-09-20T13:19:22.000529Z

у меня снова все варианты в мозгах не умещаются 🙂 но еще раз спасибо вам, буду пробовать их все по очереди

misha 2017-09-20T13:19:33.000134Z

🍿

2017-09-20T13:20:08.000524Z

почему не делать так? потому что только на постгрессе будет работать?

misha 2017-09-20T13:20:19.000517Z

@anjensan а почему? медленно будет?

anjensan 2017-09-20T13:21:04.000172Z

нет. будет даже быстрее на небольших объемах (кложура то медленная) 🙂

misha 2017-09-20T13:21:12.000388Z

постгрес вроде не хипстера пишут, возможно для этого фича и есть

anjensan 2017-09-20T13:21:24.000365Z

но это по сути запихивание логики внутрь реляционки, что можно делать, если знаешь что делаешь

2017-09-20T13:21:36.000211Z

медленно... мне потом это на клиента слать - а те объемы на которых оно будет медленно, на клинта не пролезут имхо

anjensan 2017-09-20T13:22:06.000690Z

@misha если у тебя есть дырка^W фича, то не значит что нужно с ней делать все подряд

misha 2017-09-20T13:22:29.000302Z

мне кажется, что такой (хотя бы черновой) вариант - сильно нагляднее всех танцев с кастомными структурами данных и трансформациями. и может быть даже можно мимо кложи ответы отправлять

anjensan 2017-09-20T13:22:35.000182Z

@ivana у тебя что, ровно 1 клиент ?

anjensan 2017-09-20T13:23:02.000222Z

@misha нене. наглядность и простота сопровождения - это точно не про генерацию json на стороне постгри

2017-09-20T13:23:14.000232Z

если про апи - то нет, подразумевается что много 🙂

misha 2017-09-20T13:23:32.000329Z

@anjensan ну я не пользуюсь постгресом, и жсоны в sql базах не храню, потому не знаю зачем фича, и ради какого ююзкейса. Но не пользоваться фичей только потому что "непривычно" кому-то – такой себе аргумент

anjensan 2017-09-20T13:23:42.000100Z

@ivana ну тогда при чем тут объемы. маленький объем помножить на дофига клиентво = загруженная база

anjensan 2017-09-20T13:24:12.000060Z

@misha если кратко - релаяионку постгрю можно юзать как нереляционную базу

2017-09-20T13:24:22.000451Z

ну тут не факт что мой велик на кложе будет быстрее чем обьработка жсон в постгре

anjensan 2017-09-20T13:24:36.000442Z

как пример - запихунть полноценный джсон в 1 филд. построить индексы там полноценные и все такое

misha 2017-09-20T13:24:39.000420Z

хз, распарсить глазами 20 строк sql проще будет, чем по 3 неймспейсам кастомные трансформации вычитывать

anjensan 2017-09-20T13:25:03.000538Z

🤦 🤦 🤦

misha 2017-09-20T13:25:29.000553Z

@anjensan ну я про конкретный случай, ну. что ты сразу фейспалмишь :opieop:

anjensan 2017-09-20T13:25:33.000476Z

а ничего, что эти 20 строк тебе придется генерить из кложи динамически 😃

anjensan 2017-09-20T13:25:42.000017Z

чтобы потом это дело в graphql обернуть

2017-09-20T13:26:38.000256Z

ну так и так запросы динамически генерить. только если ответы необработанные никак, то еще их обрабатывать больше после

misha 2017-09-20T13:26:59.000529Z

вообще наверное ты прав да, с другой стороны в этом примере "генерить в кложе" отличается парой токенов row-to-json в этих селектах

misha 2017-09-20T13:27:55.000599Z

всей инфы у меня нет, но сразу отбрасывать этот вариант именно в этом случае - я бы не стал

2017-09-20T13:28:48.000086Z

а это вся инфа - мне надо запилить графкуэль апи для существующей постгресс бд.

anjensan 2017-09-20T13:28:49.000452Z

ну тут такое дело - генерить json (скажем более правильно - сериализовать. есть же еще bson, yaml, xml и прочее, юзеры апи могут предпочесть другой формат) на базе не прянято

misha 2017-09-20T13:29:27.000220Z

@ivana не знаю я как, что именно значит "запилить графкуэль апи" )

anjensan 2017-09-20T13:29:33.000384Z

1) это нагружает базу. БД обычно одна и трудно маштабируется, веб серверов много и легко накинуть еще => надо разгружать БД ка можно больше

anjensan 2017-09-20T13:30:15.000357Z

2) фиг сделаешь пособработку (скажем формат для числа сделать, или там филд переименовать. или еще чего). пихать это в базу - усложняется дебаг и поддержка

misha 2017-09-20T13:31:09.000205Z

ну, тут же можно clojure.data.json/read-string :opieop:

anjensan 2017-09-20T13:31:20.000162Z

3) структура базы должна соотв структуре твоей бизнес модели. это не всегда получается. но даже если получится... потом фиг поменяешь без жуткой боли

2017-09-20T13:31:33.000075Z

я понял, ты за разделение ответственности, чтобы база занималась только своим (условно) делом. Но если я осилю запилить другой вариант, без жсона в базе и с несколькими запросами...

anjensan 2017-09-20T13:31:54.000693Z

то лично от меня получишь значок "наркоман" 🙂

misha 2017-09-20T13:32:00.000697Z

и дальше переименовывать и тд. но да, мне "разные мелкие запросы" с этой точки зрения больше нравятся

anjensan 2017-09-20T13:32:15.000516Z

я и сам иногда страдал... поэтому понимаю как это больно 😉

2017-09-20T13:32:28.000082Z

а разве я его еще не получил за пример моего запроса и ответа выше? 😂

anjensan 2017-09-20T13:33:22.000040Z

не. ты пока только показал шприц, который я выбир из твоих рук 🙂

anjensan 2017-09-20T13:33:32.000259Z

😂

misha 2017-09-20T13:34:13.000525Z

не все наркотики одинаково тяжелы :d:

2017-09-20T13:35:06.000223Z

ладно, если серьезно, есть 2 условно приемлемых варианта - несколько запросов и выгребание их в Кложе с заполнением нужной иерархической структуры, и вариант вешать логику компоновки жсонов на базу, так?

2017-09-20T13:36:00.000217Z

а то вы накидываете инфы, для вас она известная, а мне надо сориентироваться 🙂

anjensan 2017-09-20T13:36:18.000039Z

нет. есть условно 1 вариант - несколько запросов к базе в одной транзакции

👍 1
✅ 2
2017-09-20T13:37:07.000064Z

то есть мне надо повторить подвиг создателей джойнмонстра по ссылке выше 🙂 понятно 🙂

misha 2017-09-20T13:37:33.000633Z

это сильно меньше подвиг чем альтернатива (если тебе универсальный эндпоинт нужно)

2017-09-20T13:38:25.000023Z

обнадеживаешь, я навскидку почитал и испугался, думал там совсем капец.

2017-09-20T13:38:46.000619Z

но мне еще sql осилить на базовом уровне надо, да

misha 2017-09-20T13:38:51.000208Z

раскладываешь на плоские sql запросы, заворачиваешь в транзакцию

2017-09-20T17:11:02.000053Z

кстати эта, показываю ментору то что наработал на текущий момент (да-да, весь этот наркоманский алгоритм с кривыми запросами 🙂 ), может вы что подскажете по коду - как надо, как нельзя, за что руки оторвать, но только конструктивно - с указанием на что заменить и как правильно 🙂 https://github.com/Ivana-/GraphQL-Postgres-backend-test-1/blob/master/src/project_lein_1/core.clj

razum2um 2017-09-20T17:59:01.000128Z

как вы скажете по-русски “nil punning” ?

misha 2017-09-20T18:51:13.000101Z

:d:

mike_ananev 2017-09-20T18:56:39.000196Z

http://www.java9countdown.xyz

mike_ananev 2017-09-20T18:56:42.000380Z

ждемс

dottedmag 2017-09-20T18:57:31.000463Z

Каламбур ничтозации

mike_ananev 2017-09-20T19:37:06.000602Z

кто-нибудь знает, lein для 9 починили?

dbushenko 2017-09-20T20:45:52.000637Z

Кто-нибудь юзал integrant? Как он вообще?