Павел
лично я (чисто в рамках поболтать) не люблю вендор-лок на всякие высокоуровневые либы, пользы от симфони/кэщ, мессенджера, локера и многих вещей не особо очевидна. ну тебе реально не нужен адаптер чтобы и в файлы, и в мемкеш, и в редис и еще в два десятка разных стораджей умел. скорее всего, тебе нужен конкретно редис-кеш с какими-то редис-специфик фичами, но они будут скрыты за этим мегауниверсальным адаптером. да, ты выиграешь если сменишь редис на мемкеш, например, но как часто это делается в реальных проектах? зато если они решат всё изменить, сломать и переделать, ты никуда не денешься, придется пользоваться. поэтому я стараюсь в своих командах не блокироваться на симфони-компоненты, если их без особых затрат можно заменить на своё
Очень здраво, но пилить свое вместо готового тоже такое себе. В идеале завертеться на свой интерфейс или сильно не выходить в вендорный. Вроде как симфони кэш минимальный интерфейс для работы, чтобы его быстро сменить на своб реализацию, в случае чего. Но вот теги - магия
Konstantin
у меня какие претензии: мне иногда нужны другие операции от редиса: hset, lpush там не знаю, тысячи их. и часто бывает что в одном классе-сервисе у меня и symfony/cache болтается, и тут же рядом "сырой" redis-клиент для тех операций, что не укладываются в рамки интерфейса кеш-адаптера
Konstantin
и, спрашивается, а нахера мне это всё, если я могу той же одной строчкой сделать не $item->save(), а $redis->set(....)
Павел
та никакой магии. очень удобная штука :) пробуйте
Магия под капотом. Я если честно даже не разобрался какой тип данных создаётся) ещё с редисом опыта мало. Верхоуровневое использование то понятно: тегнул, инвалиднул тег - изи)
Andrii
и в таком случае иметь классы для кеша и классы для работы с другими методами redis самое то
Konstantin
вы мешаете кеш и работу с редисом как базой. это разные вещи
да не, я понимаю что мешаю, я и говорю, а зачем мне тогда универсальный адаптер всех-на-свете-баз, если я в этом проекте УЖЕ завендорлочен на редис?
Andrii
да не, я понимаю что мешаю, я и говорю, а зачем мне тогда универсальный адаптер всех-на-свете-баз, если я в этом проекте УЖЕ завендорлочен на редис?
затем, что вы не занимаетесь разработкой клиента для cache, плюс тегированием и всем остальным, что в рамках кеширования используется, так как оно идёт из коробки, а тратите время только на своё детище, которое уже не кеш, а работа с базой.
Konstantin
ничо не понял опять. кеш - это не только get/set/del - это чуть больше операций (как минимум транзакционность). и далеко не всегда я могу уложить свои операции в интерфейс адаптера
Konstantin
если мне нужно больше чем get/set - я вынужден отказаться от либы. но для чего мне тогда кеш-либа в целом?
Konstantin
$redis->set/get/del не занимают больше кода
Konstantin
теггирование - ок, аргумент. но оно, во-первых, не всегда нужно. во-вторых, реализуется не через такую жопу, как это сделано в симфони
Andrii
Магия под капотом. Я если честно даже не разобрался какой тип данных создаётся) ещё с редисом опыта мало. Верхоуровневое использование то понятно: тегнул, инвалиднул тег - изи)
если я правильно помню, то когда создаётся тег для записи, то в кеше создаётся, ещё несколько записей. и потом, когда инвалидируется по тегу, то эти доп записи обновляются (типа смена версии была 1, а стала 2) и все, что было подмечено тегом с версией 1 становится не валидным (ключи и данные остаются, но версия меняется. со временем оно почистится).
Павел
если я правильно помню, то когда создаётся тег для записи, то в кеше создаётся, ещё несколько записей. и потом, когда инвалидируется по тегу, то эти доп записи обновляются (типа смена версии была 1, а стала 2) и все, что было подмечено тегом с версией 1 становится не валидным (ключи и данные остаются, но версия меняется. со временем оно почистится).
Не, там создается какой то тип данных с названием тега. Я думал что cет или хэш. Но не угадал, и разобраться не получается. TYPE тоже не показывает. Судя по всему там хранится список key. Когда тег инвалидируется то удаляется как эта запись, так и key:value элементов. Под капотом создается какой то цикл на Lua и гоняется в поисках элементов и удаления.
Konstantin
а можно пример, что ещё в рамках кеширования вы, используете?
навскидку - флаг nx из set-a, чтобы атомарно записать если нет такого ключа
Павел
не, не может быть там lua. ибо тогда не будет тегирования у memcached
На каждый адаптер своя реализация тегирования
Andrii
На каждый адаптер своя реализация тегирования
возможно, не буду спорить, коаырял давно
Andrii
навскидку - флаг nx из set-a, чтобы атомарно записать если нет такого ключа
извиняюсь, пока ничего не могу сказать, у меня дождь пошёл::)
Konstantin
извиняюсь, пока ничего не могу сказать, у меня дождь пошёл::)
да я не имею цели переубедить или поспорить, так, поболтать под конец дня, наболевшим поделиться)
Shokha
Добрый день! Запустил команду php bin/console d:m:m все успешно завершилось! но если опять запустить эту команду сразу он питается запустить опять те файлы миграции который уже success
Vlad
так в чем проблема? Скажет что эта уже миграция накатана и все
Shokha
так в чем проблема? Скажет что эта уже миграция накатана и все
Он питается еще раз накатить миграции) И по этому сразу уже получает ошибку типа такая таблица уже существует
Konstantin
руками таблицу migrations_versions не сносили? не чистили?
Konstantin
выглядит как криворучие где-то в этом месте
Shokha
выглядит как криворучие где-то в этом месте
Делал тогда когда вес базу сносил
Shokha
выглядит как криворучие где-то в этом месте
Сносил вес базу и на локалке и на сервере! Удалил вес файлы миграции Создал новый БД Создал новый файлы миграции Опят тоже самая ошибка! Только на сервере(pgsql 9) такая ошибка Локале(pgsql12) все нормально!
Konstantin
господи, в этом чате когда-нибудь будут нормальные вопросы а не "помогите, я сделяль, но плохо"
Konstantin
Сносил вес базу и на локалке и на сервере! Удалил вес файлы миграции Создал новый БД Создал новый файлы миграции Опят тоже самая ошибка! Только на сервере(pgsql 9) такая ошибка Локале(pgsql12) все нормально!
ты создаешь базу, подозреваю, командами симфони - типа schema:create etc, не помню как их. они создают уже НОВУЮ базу, с твоими новыми полями, на данный текущий момент. миграции про это ничего не знают, и пытаются повторно добавить эти поля
Konstantin
что делать: 1) не создавать базу командами симфони или как-то иначе. изначальный ddl базы - это первая миграция, дальше любые изменения через них 2) если это уже случилось - штош, удаляем все миграции и считаем текущую точку отсчета началом времен, последующие миграции будут начинаться отсюда
Shokha
Shokha
Konstantin
разные схемы, базы, таблицы?
Konstantin
./bin/console doctrine:migrations:list
Konstantin
/bin/console doctrine:migrations:status
Konstantin
ровно то же самое, что и в тулбаре
Konstantin
у вас конфиг бандла смотрит в одно место, а селектите руками - из другого. перепутали схему/базу, либо имя таблицы с миграциями поменялось
Shokha
Там только одна база есть больше нечего
Konstantin
тогда это, наверное, космические лучи выбили ячейку памяти, я тут бессилен
Shokha
кеш конфига почистить?
Только что сделал не помог
Shokha
Опять создал новый БД только уже с другой названой! Все равно тоже саоме) Лан если найду решения буду поделится) пойду ищу где накосячиль
Алексей
.env глянь может прод с разработкой разные
Konstantin
боюсь что ошибку покажет))
Shokha
боюсь что ошибку покажет))
Потому что у него команде опечатка или что?
Konstantin
в имени таблицы
Konstantin
так нечестно)
Kirill
Всем привет! Подскажите, как можно добавиться следующего? У меня есть АПИ, которая возвращает все отделы компании с кучей информации, например, количеством сотрудников в самом отделе и всех дочерних отделах, количестве сотрудников по тегам и тд. Все это жутко медленно работает, потому что сейчас сначала достаются отделы из базы, а затем в цикле для каждого отдела считается вся эта информация. Я все это переписал на один большой SQL запрос, все стало работать быстро, но у меня проблема. Я запрос выполняю вот так $query = $this->connection->executeQuery($sql, $params); $results = $query->fetchAllAssociative(); Мне массив приходит, где каждое поле - это число, строка и тд. Но мне в этом массиве нужно некоторые поля получать как объекты entity, а сейчас мне приходят айдишники. Сейчас, чтобы добиться желаемого, мне нужно полученный массив в цикле прогнать и найти entity для каждой записи, но я точно знаю, что как-то можно выполнив сырой запрос сразу замаппить entity для некоторых полей. Надеюсь, смог понятно описать, что мне нужно.
Павел
Всем привет! Подскажите, как можно добавиться следующего? У меня есть АПИ, которая возвращает все отделы компании с кучей информации, например, количеством сотрудников в самом отделе и всех дочерних отделах, количестве сотрудников по тегам и тд. Все это жутко медленно работает, потому что сейчас сначала достаются отделы из базы, а затем в цикле для каждого отдела считается вся эта информация. Я все это переписал на один большой SQL запрос, все стало работать быстро, но у меня проблема. Я запрос выполняю вот так $query = $this->connection->executeQuery($sql, $params); $results = $query->fetchAllAssociative(); Мне массив приходит, где каждое поле - это число, строка и тд. Но мне в этом массиве нужно некоторые поля получать как объекты entity, а сейчас мне приходят айдишники. Сейчас, чтобы добиться желаемого, мне нужно полученный массив в цикле прогнать и найти entity для каждой записи, но я точно знаю, что как-то можно выполнив сырой запрос сразу замаппить entity для некоторых полей. Надеюсь, смог понятно описать, что мне нужно.
Если это чтение - то скорее всего вы делаете что-то не так, раз вам нужна сущнось. Если это запись, то можно прогнать по ID и получить сущности (1,2 доп запроса по первичным ключам - ничего страшного), либо ваш запрос переписать на REsultSetMapping
Павел
Но я больше склоняюсь к первому
Павел
Опять таки самый короткий ответ - зачем вы гоняете в цикле запросы, если можно сделать findbyIds(array ids)
Nikolay
Всем привет! Подскажите, как можно добавиться следующего? У меня есть АПИ, которая возвращает все отделы компании с кучей информации, например, количеством сотрудников в самом отделе и всех дочерних отделах, количестве сотрудников по тегам и тд. Все это жутко медленно работает, потому что сейчас сначала достаются отделы из базы, а затем в цикле для каждого отдела считается вся эта информация. Я все это переписал на один большой SQL запрос, все стало работать быстро, но у меня проблема. Я запрос выполняю вот так $query = $this->connection->executeQuery($sql, $params); $results = $query->fetchAllAssociative(); Мне массив приходит, где каждое поле - это число, строка и тд. Но мне в этом массиве нужно некоторые поля получать как объекты entity, а сейчас мне приходят айдишники. Сейчас, чтобы добиться желаемого, мне нужно полученный массив в цикле прогнать и найти entity для каждой записи, но я точно знаю, что как-то можно выполнив сырой запрос сразу замаппить entity для некоторых полей. Надеюсь, смог понятно описать, что мне нужно.
Сущности для чего нужны?
Kirill
АПИ отдает ДТО. Мне чтоб ДТО заполнить нужна сущность
Kirill
вот смотрите, допустим у меня sql возвращает три поля id, title, head_id. Мне нужно, чтоб на основании head_id я сущность User получил. Мне как будто бы вот это нужно https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/native-sql.html Но вчера попробовал, ничего не получилось)
Kirill
Опять таки самый короткий ответ - зачем вы гоняете в цикле запросы, если можно сделать findbyIds(array ids)
я могу, конечно, отдельно получить сущности одним запросом и смапить их вручную. Но я ищу встроенный инструмент для этого
Kirill
спасибо!
Павел
Но я бы посмотрел в сторону того, что вы что-то делаете не так в логике, что вам нужна сущность чтобы заполнить ДТО чтения. Посмотрите в сторону сохранения данных, а не их вычисления реалтайм на read. Или создания сервиса, который будет использоваться и в и чтении (в DTO) и в записи (Entity) (хотя возможно кастыль)
Павел
Опять таки модель чтения - это не прям DTO, это модель
Павел
Наполните ее логикой вычисления если это требуется.
Konstantin
начните с того, что у вас апи очень перегружено, это путь вникуда - джойнить, джойнить и джойнить ради одного ответа. факт того, что это уже не очень удобно делать через орм об этом и говорит. тут либо дробить апи на более мелкие, либо graphql
The Ant
Всем привет! Подскажите, как можно добавиться следующего? У меня есть АПИ, которая возвращает все отделы компании с кучей информации, например, количеством сотрудников в самом отделе и всех дочерних отделах, количестве сотрудников по тегам и тд. Все это жутко медленно работает, потому что сейчас сначала достаются отделы из базы, а затем в цикле для каждого отдела считается вся эта информация. Я все это переписал на один большой SQL запрос, все стало работать быстро, но у меня проблема. Я запрос выполняю вот так $query = $this->connection->executeQuery($sql, $params); $results = $query->fetchAllAssociative(); Мне массив приходит, где каждое поле - это число, строка и тд. Но мне в этом массиве нужно некоторые поля получать как объекты entity, а сейчас мне приходят айдишники. Сейчас, чтобы добиться желаемого, мне нужно полученный массив в цикле прогнать и найти entity для каждой записи, но я точно знаю, что как-то можно выполнив сырой запрос сразу замаппить entity для некоторых полей. Надеюсь, смог понятно описать, что мне нужно.
я бы прямо в бд джойнил, агрегировал и всё вложенное в жжейсон. на выходе получишь готовые объекты
Kirill
начните с того, что у вас апи очень перегружено, это путь вникуда - джойнить, джойнить и джойнить ради одного ответа. факт того, что это уже не очень удобно делать через орм об этом и говорит. тут либо дробить апи на более мелкие, либо graphql
Ну зачем? Есть страница, на который отображается структура компании. Отделы в виде дерева. Под каждый отделом информация о нем. Запрос тяжёлый из-за того, что там много count, причем рекурсивных. Такой запрос не может быть быстрым, потому что count, а отделов больше тысячи и несколько тысяч сотрудников. Но это не проблема, результат кэшируется и раз в час обновляется.
Konstantin
затем что с подобными апи тяжело работать (вы сами с этим столкнулись уже), тяжело кешировать, тяжело инвалидировать кеш, тяжело запросы писать. для решения подобных проблем придумали api gateway. ваше приложение отдает набор рестфул-апишек, а какая-то умная штука умеет сама из джойнить в большой денормализованный ответ для, например, мобильного приложения
Konstantin
наворачивать функционал в это апи - это путь вникуда, это уже сейчас кусок слабоподдерживаемого кода, а будет только хуже
Kirill
Это все хорошо, конечно. Но времени на все это нет)