인프런 커뮤니티 질문&답변

salus82님의 프로필 이미지

작성한 질문수

[리뉴얼] React로 NodeBird SNS 만들기

Sequelize.literal을 사용하여 게시글 가져오기 문의

20.11.22 22:30 작성

·

661

0

Sequelize.literal을 사용하고 싶어 문의드립니다.
1 해당 쿼리를 사용해서 LikeCount가 높은 순으로 게시물을 가져오고 싶은데 다음과 같은 에러가 납니다.

SequelizeDatabaseError: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT PostId, count(*) as LikeCount FROM Dev.Like Group BY PostId ORDER BY `Pos' at line 1

2 다른 쿼리를 사용해서 최근 작성된 게시글을 15개만 가져옵니다. 같은 에러가 나네요.  
SequelizeDatabaseError: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM Dev.posts order by createdAt DESC limit 0, 15; ORDER BY `Post`.`cr' at line 1

답변 12

0

salus82님의 프로필 이미지
salus82
질문자

2020. 12. 08. 12:01

아아앗............제가 잘못 생각해서 딴곳만 봤네요..죄송합니다..잘 작동됩니다.

감사합니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2020. 12. 07. 21:26

지금까지 계속 Coment.findAll 쪽 코드로 질문을 주셨는데, 실제로 prePost의 결과는 있지 않나요?

id: {[Op.in]: prePost.map((v) => v.id)} 하셨는데 attributes가 PostId랑 Count(*)이라서 id가 없는 것 아닌가요?

0

salus82님의 프로필 이미지
salus82
질문자

2020. 12. 07. 18:07

네 저도 그점이 이상해서요. 

routes> posts.js 코드입니다.

const express = require('express');
const { Op } = require('sequelize');
const Sequelize = require('sequelize');

const { Post, Image, User, Comment } = require('../models');

const router = express.Router();

router.get('/', async (req, res, next) => { // GET /posts
try {
const prePost = await Comment.findAll({
limit: 2,
group: ['PostId'],
attributes: ['PostId', [Sequelize.literal('count(*)'), 'CommentCount']],
order: [
[Sequelize.literal('CommentCount'), 'DESC'],
],
});
const where = {
id: {[Op.in]: prePost.map((v) => v.id)}
};
const posts = await Post.findAll({
where,
include: [{
model: User,
attributes: ['id', 'nickname'],
}, {
model: Image,
}, {
model: Comment,
include: [{
model: User,
attributes: ['id', 'nickname'],
}],
}, {
model: User, // 좋아요 누른 사람
as: 'Likers',
attributes: ['id'],
}, {
model: Post,
as: 'Retweet',
include: [{
model: User,
attributes: ['id', 'nickname'],
}, {
model: Image,
}]
}],
});
console.log(posts);
res.status(200).json(posts);
} catch (error) {
console.error(error);
next(error);
}
});

module.exports = router;

그리고 코드를 실행하면 다음과 같이 200코드와 빈 배열이 나타납니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2020. 12. 07. 15:01

이 쿼리를 노드로 실행하면 문제없지 않나요? 제가 알기로는 `Dev`를 붙여야하는 건 워크벤치 특성입니다. 워크벤치에서는 Dev말고 다른 DB까지 다 볼 수 있어서요. 그런데 노드에서는 Dev를 안 붙여도 돌아갑니다. 왜냐하면 처음에 config.json으로 database로 Dev를 설정했으니까요.

0

salus82님의 프로필 이미지
salus82
질문자

2020. 12. 07. 14:39

네 선생님 빨간 박스 부분을 누르면 다음과 같이 나옵니다.

생성된 SQL(워크벤치에서 오류가 나옵니다.)

SELECT `PostId`, count(*) AS `CommentCount` FROM `comments` AS `Comment` GROUP BY `PostId` ORDER BY CommentCount DESC LIMIT 2;

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2020. 12. 07. 14:25

이게 사실 Dev를 붙이나 안 붙이나 상관 없어야 합니다. 워크벤치에서 오류 메시지를 알려주시겠어요?

0

salus82님의 프로필 이미지
salus82
질문자

2020. 12. 07. 11:36

선생님, 조금씩 변경하면서 해보니 말씀하신 sql 생성에서 `Dev`스키마가 빠져서 나옵니다.

코드

const prePost = await Comment.findAll({
limit: 2,
group: ['PostId'],
attributes: ['PostId', [Sequelize.literal('count(*)'), 'CommentCount']],
order: [
[Sequelize.literal('CommentCount'), 'DESC'],
],
});
const where = {
id: {[Op.in]: prePost.map((v) => v.id)}
};

생성된 SQL(워크벤치에서 오류가 나옵니다.)

SELECT `PostId`, count(*) AS `CommentCount` FROM `comments` AS `Comment` GROUP BY `PostId` ORDER BY CommentCount DESC LIMIT 2;

작동되는 SQL( FROM `comments` -> FROM `Dev`.`comments` )

SELECT `PostId`, count(*) AS `CommentCount` FROM  `Dev`.`comments` AS `Comment` GROUP BY `PostId` ORDER BY CommentCount DESC LIMIT 2;

 `Dev`스키마만 추가되는 SQL이 되는데, 이 부분 문의드립니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2020. 11. 27. 13:14

제 생각에는 서브쿼리를 쓰실 때 서브쿼리를  ()로 안 감싼 것 같습니다. Sequelize.literal에서 '(SELECT ...)'를 해보세요.

Select * from 테이블 where 컬럼 in (select * from 다른거);

이런 식이 되어야 해서요.

0

salus82님의 프로필 이미지
salus82
질문자

2020. 11. 27. 12:00

네 선생님

1 은 SQL이 생성되지 않고 TypeError: Cannot read property '_modelAttribute' of undefined 으로만 나옵니다.

2의 SQL은 SELECT * FROM `Dev`.`posts` order by `createdAt` DESC limit 0, 15 ORDER BY `Post' 이 나오고 워크벤치에서는 쿼리란에 넣으면,

쿼리로 인식이 안됩니다.

1의 경우에는 Like테이블에서 PostId를 가져와서 Post테이블에 적용하는 부분이 문제가 있어 보이는데, 이 뒷부분을 어떻게 할 지 모르겠습니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2020. 11. 24. 17:51

스키마와 테이블명은 `Dev`.`posts` 이런 식으로 하셔야 합니다. 그리고 SQL도 같이 올려주세요.

0

salus82님의 프로필 이미지
salus82
질문자

2020. 11. 24. 17:05

네 선생님 말씀대로 진행하니 다른 에러가 납니다. 

1. TypeError: Cannot read property '_modelAttribute' of undefined 

const where = {
PostId: {[Op.in]:
Sequelize.literal('SELECT `PostId`, count(*) as `LikeCount` FROM `Dev.Like`')}
};
//중략
order: [
['LikeCount']
[Comment, 'createdAt', 'DESC'],
],
2. SequelizeDatabaseError: You have an error in your SQL syntax; check the manual
const where = {
PostId: {[Op.in]:
Sequelize.literal('SELECT * FROM `Dev.posts` order by `createdAt` DESC limit 0, 15')}
};
// 중략
order: [
['createdAt', 'DESC'],
[Comment, 'createdAt', 'DESC'],
],
 워크벤치의 번개표시와 그 옆 버튼을 눌러도 오류 원인을 알 수 없어서 이어 여쭙니다.

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

2020. 11. 22. 22:40

Dev같은 스키마나 posts같은 테이블, createdAt같은 컬럼명을 ``으로 묶어보세요. 생성해준 SQL이 터미널에 기록되는데 그걸 워크벤치에서 그대로 복붙해서 실행해보시면 더 자세한 에러 위치를 알 수 있습니다.

salus82님의 프로필 이미지

작성한 질문수

질문하기