i tried to CRUD like this ```await prisma.A.creat...
# orm-help
l
i tried to CRUD like this
Copy code
await prisma.A.create({ data }).then((e) => {
	await prisma.B.delete({ where: { seq: e.seq } });
});
but delete API didn’t work even create was successed. can i get help with it?
a
could it be a typo in.
.them
?
l
i fixed wrong grammer cuz i have to write on notepad insteadof IDE.
please nevermind of grammar or misspelling 🙂
👍 1
a
Are you sure you can find in B where
seq
is
seq
from A?
f
Why are you awaiting everything?, you cant await the second thing because it’s not an async function
Copy code
const e = await prisma.A.create({ data });
await prisma.B.delete({ where: { seq: e.seq } });
Or using regular then
Copy code
prisma.A.create({data})
  .then(e => prisma.B.delete({
    where: { seq: e.seq }
  }))
đź’Ż 1
r
Yes what @Fran Zekan has suggested should work.
l
thank you guys.
i just have one more curiosity.
i can i test the speed of delete and deleteMany in code?
Wait. Prisms API won’t work without await isn’t it?
b
there are two ways to handle async (promise) functions. the first is to use
await
in front of the function, the other is to use
.then() / .catch()
after the function https://levelup.gitconnected.com/async-await-vs-promises-4fe98d11038f
Saw you just deleted the last post. Did it work?
l
Copy code
prisma.posts.findMany().then((posts) => {
			log('target posts ', posts.length);
			posts.forEach(
				({ author, content, create_dt, flag, from, hit, link, seq: origin_seq, title, upload_date }) => {
					const data: past_postsCreateInput = {
						from,
						link,
						title,
						author,
						content,
						flag,
						hit,
						upload_date,
					};

					prisma.past_posts
						.create({ data })
						.then(({ seq }) => {
							log(`CREATE ${seq}`);
							prisma.posts.delete({ where: { seq: origin_seq } }).then(({ seq: delete_seq }) => {
								log(`DELETE ${delete_seq}`);
							});
						})
						.catch((e) => {
							e;
						});
				},
			);
		});
delete API isn’t fired even thow seq is exist on table posts that’s why i made this inquery
oh i just wanted to tidy up the messed message
b
So you’re code is getting into something called “callback hell” where you have a lot of nested
.then()
calls. Go for something more like this
Copy code
const posts = await prisma.posts.findMany()
log("target posts ", posts.length);

for await (const post of posts) {
  const data: past_postsCreateInput = {
    from: post.from,
    link: post.link,
    title: post.title,
    author: post.author,
    content: post.content,
    flag: post.flag,
    hit: post.hit,
    upload_date: post.upload_date,
  };

  const newPost = await prisma.past_posts.create({ data })
  log(`CREATE ${newPost.seq}`);

  const deletedPost = await prisma.posts.delete({ where: { seq: origin_seq } });
  log(`DELETE ${deletedPost.delete_seq}`);
}
Curious to hear if that makes a difference
l
let me try
b
It’s worth checking to see if there actually is something in
Posts
with the
origin_seq
l
Copy code
const movePostsToPastPosts = async () => {
	const posts = await prisma.posts.findMany();
	log('target posts ', posts.length);

	for await (const { from, link, title, author, content, flag, hit, upload_date, seq } of posts) {
		const data: past_postsCreateInput = {
			from,
			link,
			title,
			author,
			content,
			flag,
			hit,
			upload_date,
		};

		const newPost = await prisma.past_posts.create({ data });
		log(`CREATE ${newPost.seq}`);
		const deletedPost = await prisma.posts.delete({ where: { seq } });
		log(`DELETE ${deletedPost.seq}`);
	}
};
it worked. but the reason that i put CRUD into then() was to reduce declare one shot variable and readable.
however youre way of approach changed my though.
the problem was forEach
Copy code
const movePostsToPastPosts = async () => {
	const posts = await prisma.posts.findMany();
	log('target posts ', posts.length);

	// for await (const { from, link, title, author, content, flag, hit, upload_date, seq } of posts) {
	await posts.forEach(async ({ from, link, title, author, content, flag, hit, upload_date, seq }) => {
		const data: past_postsCreateInput = {
			from,
			link,
			title,
			author,
			content,
			flag,
			hit,
			upload_date,
		};

		const newPost = await prisma.past_posts.create({ data });
		log(`CREATE ${newPost.seq}`);
		const deletedPost = await prisma.posts.delete({ where: { seq } });
		log(`DELETE ${deletedPost.seq}`);
	});
};
b
yea you can’t do await inside forEach
damn. i didn’t know about that..
so much thanks Ben!
b
If you ever need to do aysync insisde a forEach loop there is a pretty simple function you can use https://gist.github.com/Atinux/fd2bcce63e44a7d3addddc166ce93fb2
a
@Logan Lee if you want to avoid
for
and use the array methods like
.map
or
.forEach
, you need to be aware of this:
.forEach
doesn’t expect you to return anything, so it will simply blindly skip anything you return. In this case you are returning promises in that array (you are calling promise methods for each element), so you need to return those promises to await them or your program will finish before they complete. One way is to do it with
for
as suggested by @Ben Schwartz. The only problem is that you are awaiting each operation to be performed one-by-one. If you want concurrency, you can use
.map
in a similar fashion as you were using
.forEach
, but you need to make sure you await all the promises you are returning:
Copy code
prisma.posts.findMany().then((posts) => {
  log('target posts ', posts.length);

  const allPostPromises = posts.map(
    ({ author, content, create_dt, flag, from, hit, link, seq: origin_seq, title, upload_date }) => {
      const data: past_postsCreateInput = {
        from,
        link,
        title,
        author,
        content,
        flag,
        hit,
        upload_date,
      };

      // We need to return the promise
      return prisma.past_posts
        .create({ data })
        .then(({ seq }) => {
          log(`CREATE ${seq}`);
          // returning the promise
          return prisma.posts.delete({ where: { seq: origin_seq } }).then(({ seq: delete_seq }) => {
            log(`DELETE ${delete_seq}`);
          });
        })
        .catch((e) => {
          e;
        });
    },
  );

  // Let's return the promise that wraps all the list of promises we've created;
  return Promise.all(allPostPromises);
});
FYI: creating
async
methods and `await`ing the promises to finish can achieve a similar result. Following your last example:
Copy code
const movePostsToPastPosts = async () => {
  const posts = await prisma.posts.findMany();
  log('target posts ', posts.length);
  
  await Promise.all(
    posts.map(async ({ from, link, title, author, content, flag, hit, upload_date, seq }) => {
      const data: past_postsCreateInput = {
        from,
        link,
        title,
        author,
        content,
        flag,
        hit,
        upload_date,
      };
      const newPost = await prisma.past_posts.create({ data });
      log(`CREATE ${newPost.seq}`);
      const deletedPost = await prisma.posts.delete({ where: { seq } });
      log(`DELETE ${deletedPost.seq}`);
    })
  );
};
As mentioned earlier, with
.map
you’ll achieve concurrency (all the posts are created y and deleted in parallel), instead of going one by one as you’d do with a
for
loop. But beware,
Promise.all
will fail as soon as 1 of the promises throws an error. You might want to use
Promise.allSettled
(only available in NodeJS v12.9+) if you want to wait for all the promises to be completed (even when some have failed).
b
@afharo great advice. worthy of a stackoverflow answer. a lot of people struggle with this
🧡 1
l
@afharo Oh My Goodness so much thank you for your advice. i will try to refactor my code based on your advice when the time comes.
🧡 1