Size: a a a

Sequelize - community (eng/ru)

2019 November 11

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
Добрый вечер, коллеги. Очень рад, что нашёл этот чат. К сожалению, пока имею очень мало опыта и некоторое непонимание при освоении ORM.
источник

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
Проясните, пожалуйста, как реализовывают такой кейс: создание НОВОГО объекта, с вложенным (НО при этом вложенный уже существует в базе и его не нужно заново создавать, его нужно просто достать из базы и привязать в создаваемом объекте). Или может другим словами вызвать у модели метод .create(), а для вложенных сущностей .findOrCreate().

И для примера: имеются две модели Post и Tag связанные отношением многие-ко-многим.
Для простоты понимания оставляю самое необходимое:
Post.create(req.body, {include: [Tag]})

И для создания подаю такой объект:
{
"text": "some text",
"Tags": [
 {"id": 1}
 ]
}

Тег с id=1 существует в базе. Я не хочу его создавать, я хочу, чтобы он был просто привязан к новому создаваемому посту.
Но sequelize для этого вложенного объекта тоже пытается применить операцию по созданию и выдаёт ошибку 23505 "Ключ "(id)=(1)" уже существует."
источник

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
Я догадываюсь, что это очень частая и какая-то очевидная операция, но почему-то я толком не смог найти именно такого примера реализации. Или просто не вижу описания такого кейса в документации к sequelize. В общем потратил уже потратил много времени. Подскажите, пожалуйста, куда копать.
источник

A

Andrei in Sequelize - community (eng/ru)
источник

A

Andrei in Sequelize - community (eng/ru)
const post = await Post.create(smth)
await post.addPostTag(tagId)
источник

A

Andrei in Sequelize - community (eng/ru)
что-то около такого, метод addPostTag в данном случае динамический, как он будет называеться зависит от того, как пропишешь связи
источник

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
Andrei
что-то около такого, метод addPostTag в данном случае динамический, как он будет называеться зависит от того, как пропишешь связи
Андрей, спасибо за помощь. Правда я немного в недоумении теперь. Или даже в шоке 😰 Придется это всё руками делать((
Мне почему-то казалось, что в наиболее популярных и продвинутых ORM работа с БД реализована так, чтобы взять на себя все рутинные операции. А здесь получается, что мне приходит готовый объект в JSON уже готовый по сути для сохранения, а мне придется его вручную расщепить на составные объекты (повынимать вложенные). По ним получить (не знаю как правильно выразиться) инстансы-объекты из базы. Создать изначально требуемый объект - const post = await Post.create(smth). И ещё вручную потом для каждого вынутого объекта из базы соединить с вновь созданным - await post.addTag(tag).
А представьте если Post имеют связь не с одними только лишь Tag, а с сотней других моделей? Это же сколько однотипного кода получается. Может в sequelize есть какие-то встроенные просто малоизвестные инструменты для создания объектов с вложенными уже существующими в базе объектами.
источник

A

Andrei in Sequelize - community (eng/ru)
даже не знаю что сказать по этому поводу)
ну я знаю что можно описать модель так, что можно в теории создавать к примеру посты и теги, вот как это бы выглядело в случае один ко многим:
 const post = await Post.create({
       ...postdata,
        PostTags: arrayOfPostTags,
   }, {
       include: [
           {
               association: Post.PostTags,
           },
       ],

   });
но у меня с таким подходом возникало много проблем

а для того чтобы добавить к постам тэги(которые уже существуют в бд) ненадо вытягивать их инстансы. Просто создаешь пост - const postInstance= await Post.create(smth) , а потом сетишь связи со всеми нужными тэгами await post.setTags(arrTagsIds), т.е. сами тэги вытягивать с базы не нужно, достаточно их айдишки которые прийдут с фронта

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

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

P.S. мне сиквалайз очень не нравится, но альтернативы я не знаю)
источник
2019 November 12

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
Andrei
даже не знаю что сказать по этому поводу)
ну я знаю что можно описать модель так, что можно в теории создавать к примеру посты и теги, вот как это бы выглядело в случае один ко многим:
 const post = await Post.create({
       ...postdata,
        PostTags: arrayOfPostTags,
   }, {
       include: [
           {
               association: Post.PostTags,
           },
       ],

   });
но у меня с таким подходом возникало много проблем

а для того чтобы добавить к постам тэги(которые уже существуют в бд) ненадо вытягивать их инстансы. Просто создаешь пост - const postInstance= await Post.create(smth) , а потом сетишь связи со всеми нужными тэгами await post.setTags(arrTagsIds), т.е. сами тэги вытягивать с базы не нужно, достаточно их айдишки которые прийдут с фронта

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

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

P.S. мне сиквалайз очень не нравится, но альтернативы я не знаю)
Андрей, ещё раз спасибо за уделяемое мне время и подробный ответ. 🤝
Попробовал воспользоваться методомами подобными: post.addTag()
источник

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
1️⃣
Работает как и описано в документации, и то как вы и говорили: метод принимает либо инстанс из базы, либо integer (primary key). 👍
Вот только я не разобрался в документации по поводу передачи в этот метод объекта собранного мной, например из JSON. Можно ли? Допустим вот такого примитивного: {"id": 1}. Не срабатывает. Вызов выглядит так: post.addTag({"id": 1}). Вот хвост SQL из-за которого происходит ошибка: "AND "post_tag"."TagId" IN ('[object Object]');" Как видите после оператора IN sequelize вставляет объект, а не integer.
post.addTag({"id": 1}, {"raw": true}) - в документации про такую опцию прочитал, но она тоже не помогает.
источник

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
2️⃣
Но больше всего меня интересует вопрос с передачей в метод числа: post.addTag(int). Id-шники же нужно валидировать перед передачей в метод? То есть проверить существует ли объект с таким id в базе? Проверяем-вызываем tag.findByPk(int) и вот уже у нас уже в память загружен инстанс из базы. И в одиноком id как бы и пропадает необходимость, можно сразу оперировать целым объектом.
источник

YZ

Yaroslav Zhymkov in Sequelize - community (eng/ru)
Pizdjož Prokošek
2️⃣
Но больше всего меня интересует вопрос с передачей в метод числа: post.addTag(int). Id-шники же нужно валидировать перед передачей в метод? То есть проверить существует ли объект с таким id в базе? Проверяем-вызываем tag.findByPk(int) и вот уже у нас уже в память загружен инстанс из базы. И в одиноком id как бы и пропадает необходимость, можно сразу оперировать целым объектом.
Там нужно инстанс кидать, а не ключ
источник

YZ

Yaroslav Zhymkov in Sequelize - community (eng/ru)
В addTag
источник

A

Andrei in Sequelize - community (eng/ru)
если у вас есть таблица posts_tags с tagid и postid, то я ожидаю что tagid это foreign key на id из таблицы tag. в таком случае,на сколько я знаю, нет необходимости проверять наличие такого тега, потому что несуществующий айди вы просто не сможете добавить
источник

BD

Binyam Dele in Sequelize - community (eng/ru)
источник

BD

Binyam Dele in Sequelize - community (eng/ru)
любой ответ??
источник

YZ

Yaroslav Zhymkov in Sequelize - community (eng/ru)
You still have error with async, it's not problem with sequelize, start from read js base.
источник

BD

Binyam Dele in Sequelize - community (eng/ru)
Yaroslav Zhymkov
You still have error with async, it's not problem with sequelize, start from read js base.
else than the async is everything okay??
источник

PP

Pizdjož Prokošek in Sequelize - community (eng/ru)
Perhaps, you mix async/await and .then()?
источник

YZ

Yaroslav Zhymkov in Sequelize - community (eng/ru)
Pizdjož Prokošek
Perhaps, you mix async/await and .then()?
Yes, also problem with scope
источник