Юра
ну это прикольно, но такое себе
Юра
потому что ты либо хранишь инты, в БД ты будешь видеть инты, что не всегда удобно, либо будешь хранить строки в виде varchar
Vlad
И что
Юра
что что?
Юра
что хранить строки вмест оинтов или видеть строки вместо интов?
Vlad
В чем трабла
Vlad
Я храню все в строках
Юра
в том что есть в БД такая штука специально созданная для удобства называется она ENUM
Юра
чтобы удобно читать значения и эффетткивно хранить и индексировать
Юра
и то что доктрина в 2022 не поддерживает это нормально получается
Vlad
То как мапить данные в бд ты можешь сам указать
Юра
И сразу потерять переносимость
Юра
Просто непонятно у докирины есть вся информация чтобы нормально взять пхп энам и смапить его в платфлрмозависимый тип
Nikolay
и то что доктрина в 2022 не поддерживает это нормально получается
Этим никто не пользуется на уровне бд (к сообщению выше)
Nikolay
потому что ты либо хранишь инты, в БД ты будешь видеть инты, что не всегда удобно, либо будешь хранить строки в виде varchar
Хранишь инт или стринг, добавляешь отдельный doctrine тип, который автоматом конвертит в енам
Павел
Даже статьи есть против енамов в БД, в целом для не программиста БД звучат доводы норм. Типа обновления енамов в БД, версионирование кода.
Павел
Тема скорее всего холиварная, но значит уже не однозначная
Nikolay
Тема скорее всего холиварная, но значит уже не однозначная
Можно легко делать конвертацию через типы в коде, так что выигрыш от хранения не особо полезен
Thawne
Всем привет, у меня небольшой вопрос, делаю функцию recurring, и когда дело доходит до апи и нужно расплодить запись, скажем на год вперёд (+-200 записей может получится), то я сделал следующим образом: Циклом прохожусь от начала даты до конца и $newEntity = clone $entity; $entityManager->persist($newEntity); И в после цикла $entityManager->flush(); Вопрос такой, нормальная ли это практика? Не загнётся ли у меня апи (при условии что может быть и будет 400-500 записей)?
Сергей
Всем привет, у меня небольшой вопрос, делаю функцию recurring, и когда дело доходит до апи и нужно расплодить запись, скажем на год вперёд (+-200 записей может получится), то я сделал следующим образом: Циклом прохожусь от начала даты до конца и $newEntity = clone $entity; $entityManager->persist($newEntity); И в после цикла $entityManager->flush(); Вопрос такой, нормальная ли это практика? Не загнётся ли у меня апи (при условии что может быть и будет 400-500 записей)?
Если это одна таблица с несколькими полями, то не должно быть долго, если приложение и БД на одном сервере. Снимите метрики, посмотрите сколько времени занимает пачка в 100 штук, сколько в 200, 300, 1000 и т.д., наполните таблицу миллионом записей и сравните показания метрик. Если тайминг операции слишком большой, или приложение и БД на разных серверах, то нужно думать о пакетных операция прямым запросом, минуя сущности. Ну и про транзакцию не забудьте, помимо консистентности, пакетные вставки в одной транзакции производятся кратно быстрее.
Сергей
Понял, спасибо большое🙌🏻
Если критично через сущности сохранение, например события есть при сохраненении сущности, то - или найти вариант как тригернуть эти события, но запись всеравно производить чистым запросом - или если в АПИ не обязательно возвращать инфо о успешной записи данных, то можно операцию отправить в очередь и там сохранять сущностями сколько угодно долго - и много еще каких вариантов, решение зависит от многих факторов внутри вашего продукта
Сергей
А вообще делать в цикле persist badpractice? Если я 200 раз условно в цикле persist вызову на каждую новую сущность?
Персист это нормально, вы говорите доктрине что эту сущность нужно подготовить для сохранения. А вот флаш в цикле вызывать это плохая практика
Thawne
Персист это нормально, вы говорите доктрине что эту сущность нужно подготовить для сохранения. А вот флаш в цикле вызывать это плохая практика
Это да, он у меня после😁 ну а принципе я измерил, 2 секунды на 200 записей, при условии того что это максимум который может быть, так и оставляю, спасибо большое
Null
Подмогните, пожалуйста. Есть сущность сообщений. Есть сущность "id последнего прочитанного сообщения пользователя". Вторая сущность может еще не существовать, если он не открывал чат вовсе до сих пор. Как в рамках query билдера посчитать кол-во непрочитанных? Нюанс в том, что это - список чатов с сообщениями. Хочу в один запрос посчитать непрочитанные для каждого чата. Пришлось к голому sql прибегать. Упрощенный вариант примерно такой: SELECT COUNT(`m`.`id`) AS `cnt`, `m`.`chat_id` FROM `message` AS `m` WHERE `m`.`id` > ( SELECT `r`.`message_id` FROM `readed` AS `r` WHERE `r`.`chat_id` = `m`.`chat_id` ) OR ( SELECT `r`.`message_id` FROM `readed` AS `r` WHERE `r`.`chat_id` = `m`.`chat_id` ) IS NULL GROUP BY `m`.`chat_id`
Сергей
вроде то же самое
Null
Хм. Выглядит интересно.
Null
В sql даже работает
Null
$unreadedSubQuery = $readedRepository->createQueryBuilder('r') ->select('1') ->where('r.chat = m.chat') ->andWhere('r.message >= m') ->getQuery() ->getDQL(); $unreaded = $messageRepository->createQueryBuilder('m') ->select('COUNT(m.id) AS cnt, IDENTITY(m.user) AS user') ->andWhere("NOT EXISTS ({$unreadedSubQuery})") ->getQuery() ->getArrayResult();
Null
да
На самом деле, нет. Но это - не проблема. Я дальше превращаю это в карту id_chat => cnt И делаю $map[id_chat] ?? 0
Null
А разница?
Сергей
А разница?
по кверибилдерскому написано)
Null
Недолюбливаю этот "right way" в квери билдерах)
Павел
по кверибилдерскому написано)
Не понимаю этих expr вне жесткой динамики
Павел
На самом деле, нет. Но это - не проблема. Я дальше превращаю это в карту id_chat => cnt И делаю $map[id_chat] ?? 0
Вообще наверное еще можно через left join , но если уже все работает то нет смысла переделывать.
Null
Я думал о джойне. Не придумал за короткие сроки как это построить, высрал sql.
Null
А тут просто "под кофе" время образовалось, решил немного рефакторнуть.
Павел
Я думал о джойне. Не придумал за короткие сроки как это построить, высрал sql.
Так и надо высрать на голом sql, не обяхательно гнаться за DQL. А таблица чатов есть, или только мессаджи?
Null
Есть, но она не прибита гвоздями ни к одному из юзеров, что логично.
Null
У каждого свой "readed"
Павел
Есть, но она не прибита гвоздями ни к одному из юзеров, что логично.
Ну вообще наверное странно. Юзер же в чате сидит, должна быть связь наверное юзер-чат
Null
Да есть там все связи. Я sql намеренно упростил, чтобы лишнего не спрашивать и думать проще было. Там sql поболе был.
Павел
Да есть там все связи. Я sql намеренно упростил, чтобы лишнего не спрашивать и думать проще было. Там sql поболе был.
К чему вопрос, если вам нужны были чаты и непрочитанные, может не было смысла бы тащить мессадж таблицу.
Null
Задача получить для одного чата кол-во непрочитанных - простая. А вот чтобы получить для списка в один запрос - тут я споткнулся.
The Ant
Про оконные функции вообще что-ли никто не слышал даже?
Сергей
У кого мускул, тот скорей всего не слышал.
Сергей
В нем тоже есть
О, круто, в 8ке завезли оказывается :)
Павел
О, круто, в 8ке завезли оказывается :)
Да, 8 гораздо интереснее)
Денис
Товарищи, подскажите, пожалуйста, что не так делаю? Используется api platfrom. У сущности связь OneToMany, передаю в запросе массив связанных сущностей. Новые добавляются, но старые не удаляются. То есть, методы add и remove выполняются, у связаннйо сущности устанавливается null. Но в базе null не сохраняется
Денис
По идее, для этого нужен cascade: ['persist'] . Но он срабатывает только для сущностей, которые добавились. А remove не работает
Сергей
orphanRemoval = true
Денис
orphanRemoval = true
Так - работает. Но связанную сущность нужно не удалять, а ставить null в поле, которое связывает
Сергей
тогда не понял вопроса) я так понял нужно именно удалить. не надо удалить, а просто разлинковать - то без orphanRemoval) но чтобы у joincolumn был nullable =true
Денис
тогда не понял вопроса) я так понял нужно именно удалить. не надо удалить, а просто разлинковать - то без orphanRemoval) но чтобы у joincolumn был nullable =true
Разлинковать, да. То есть, есть метод remove, он выполняется. nullable = true в связанной сущности. На уровне обьектов все хорошо. Но в базу не сохраняется
Павел
Разлинковать, да. То есть, есть метод remove, он выполняется. nullable = true в связанной сущности. На уровне обьектов все хорошо. Но в базу не сохраняется
Проверьте что лежит в UnitOfWork. Поидее все должн лежать там. П.С. а как в итоге починили что не добавлялись ?
Денис
Проверьте что лежит в UnitOfWork. Поидее все должн лежать там. П.С. а как в итоге починили что не добавлялись ?
Не добавлялось - это глупость моя. В add методе не было $wallet->setProviderAccount(null);
Денис
В set null условие точно залетает?
Да, совершенно точно. UnitOfWork не совсем пойму, на каком этапе его смотреть? Тут запрос же через апи платформу идет
Денис
С флаша в еm и дальше в глубь
Да вроде есть . Как раз 3 затронутые сущности. С нужными изменениями
Павел
Ну тогда копать до коммита...
Денис
Ну тогда копать до коммита...
Сцуко. #[ORM\ChangeTrackingPolicy(value: 'DEFERRED_IMPLICIT')] должен быть. А не #[ORM\ChangeTrackingPolicy(value: 'DEFERRED_EXPLICIT')]
Pavel
подскажите, строка вида "\x50\x44\x46" это что вообще? Какой у нее формат?
Юра
Это закодированный юникод
Юра
Блин сижу значит три часа тут с дебагером
Юра
пытаясь понять почему не работает enumType в доктрине
Юра
а оно https://github.com/doctrine/orm/commit/d69a0fa2cfd3b883200a6324829945509f4ecc07
Юра
я так понимаю в доктрине нет никаких тестов, раз пролазят такие баги в прод
Null
🌉 Да кому нужны эти ваши тесты. Только время зря отнимают.