• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

시퀄라이즈 메소드 findOrCreate 옵션 에러

23.07.19 21:22 작성 23.07.19 21:25 수정 조회수 358

0

현재 에러

Error: Missing where attribute in the options parameter passed to findOrCreate. Please note that the API has changed, and is now options only (an object with where, defaults keys, transaction etc.)
    at Function.findOrCreate (/Users/yang-areum/Desktop/study/React-NodeBirdSNS/prepare/back/node_modules/sequelize/lib/model.js:1388:13)
    at /Users/yang-areum/Desktop/study/React-NodeBirdSNS/prepare/back/routes/post.js:50:19
    at Array.map (<anonymous>)
    at /Users/yang-areum/Desktop/study/React-NodeBirdSNS/prepare/back/routes/post.js:49:18
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
Error: Missing where attribute in the options parameter passed to findOrCreate. Please note that the API has changed, and is now options only (an object with where, defaults keys, transaction etc.)
    at Function.findOrCreate (/Users/yang-areum/Desktop/study/React-NodeBirdSNS/prepare/back/node_modules/sequelize/lib/model.js:1388:13)
    at /Users/yang-areum/Desktop/study/React-NodeBirdSNS/prepare/back/routes/post.js:50:19
    at Array.map (<anonymous>)
    at /Users/yang-areum/Desktop/study/React-NodeBirdSNS/prepare/back/routes/post.js:49:18
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
POST /post 500 17.278 ms - 820

 

번역 해본 결과 :

현재 코드 :

  • 현재 해시태그와 관련된 라우터코드만 올려보아요.

const express = require("express");
const multer = require("multer");
const path = require("path");
const fs = require("fs");

const { Post, Image, Comment, User, Hashtag } = require("../models");
const { isLoggedIn } = require("./middlewares");

const router = express.Router();

// 이미지 업로드 파일 생성
try {
  fs.accessSync("uploads");
} catch (error) {
  console.log("uploads 폴더가 없어서 맹들었슴돠 !");
  fs.mkdirSync("uploads");
}

// multer 미들웨어 : 게시물 이미지 업로드 설정
const upload = multer({
  storage: multer.diskStorage({
    destination(req, file, done) {
      done(null, "uploads");
    },
    filename(req, file, done) {
      const ext = path.extname(file.originalname); // 확장자추출(.png)
      const basename = path.basename(file.originalname, ext); // 파일명
      done(null, basename + "_" + new Date().getTime() + ext); // 파일명 + _ + 시간초 + 확장자
    },
  }),
  limits: { fileSize: 20 * 1024 * 1024 },
});

// 게시글 업로드
router.post("/", isLoggedIn, upload.none(), async (req, res, next) => {
  // POST /post
  try {
    // 해시태그 추출
    const hashtags = req.body.content.match(/#[^\s]+/g);

    const post = await Post.create({
      content: req.body.content,
      UserId: req.user.id, // 게시글을 작성한 사용자 id
    });

    // 해시태그 등록
    if (hashtags) {
      const result = await Promise.all(
        hashtags.map((tag) =>
          Hashtag.findOrCreate({
            wehre: { name: tag.slice(1).toLowerCase() },
          })
        )
      );
      console.log("HASHTAG", result);
      await post.addHashtags(result.map((v) => v[0]));
    }

    // 받은 이미지 시퀄라이즈, DB저장
    if (req.body.image) {
      if (Array.isArray(req.body.image)) {
        // 이미지를 여러개 올리면 image: [파일명.png, 파일명.png]
        const images = await Promise.all(
          req.body.image.map((image) => Image.create({ src: image }))
        );
        await post.addImages(images);
      } else {
        // 이미지를 하나만 올리면 image: 파일명.png
        const image = await Image.create({ src: req.body.image });
        await post.addImages(image);
      }
    }
    const fullPost = await Post.findOne({
      where: { id: post.id },
      include: [
        {
          model: Image,
        },
        {
          model: Comment,
          include: [
            {
              model: User, // 댓글 단 작성자
              attributes: ["id", "nickname"],
            },
          ],
        },
        {
          model: User, // 게시글 작성자
          attributes: ["id", "nickname"],
        },
        {
          model: User, // 좋아요 누른 사람
          as: "Likers",
          attributes: ["id"],
        },
      ],
    });
    res.status(201).json(fullPost);
  } catch (err) {
    console.error(err);
    next(err);
  }
});

 

혹시나 하고 시퀄라이즈에서 모델에서 코드를 잘 못 쳐서 DB가 잘못 설계 된것인가? 도 생각이 들어 코드확인과 워크밴치에서 테이블 확인했는데 문제점은 없다고 생각을 했어요.

/* models.index.js */

const Sequelize = require("sequelize");
const env = process.env.NODE_ENV || "development";
const config = require("../config/config")[env];
const db = {};

const sequelize = new Sequelize(
  config.database,
  config.username,
  config.password,
  config
);

// 시퀄라이즈에서 모델을 등록 (시퀄라이즈로 db에 require들을 넣어서 forEach문으로)
db.Comment = require("./comment")(sequelize, Sequelize);
db.Hashtag = require("./hashtag")(sequelize, Sequelize);
db.Image = require("./image")(sequelize, Sequelize);
db.User = require("./user")(sequelize, Sequelize);
db.Post = require("./post")(sequelize, Sequelize);

Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;
/* medels/post.js */

module.exports = (sequelize, DataTypes) => {
  const Post = sequelize.define(
    "Post",
    {
      // id: {}, MySQL에서 id가 자동으로 생성된다.
      content: {
        type: DataTypes.TEXT, // 글자를 무제한으로 늘려주기위해 TEXT를 사용해보았다. STRING으로 한다.
        allowNull: false,
      },
    },
    {
      // Post Module에 대한 셋팅
      charset: "utf8mb4", // 한글 + 이모티콘
      collate: "utf8mb4_general_ci", // 한글 + 이모티콘 저장
    }
  );

  // belongsTo 단수, hasMany 복수 (뒤에 s)
  Post.associate = (db) => {
    db.Post.belongsTo(db.User);
    db.Post.belongsToMany(db.Hashtag, { through: "PostHashtag" });
    db.Post.hasMany(db.Comment);
    db.Post.hasMany(db.Image);
    db.Post.belongsToMany(db.User, { through: "Like", as: "Likers" });
    db.Post.belongsTo(db.Post, { as: "Retweet" });
  };

  return Post;
};
/* models/hashtag.js */

module.exports = (sequelize, DataTypes) => {
  const Hashtag = sequelize.define(
    "Hashtag",
    {
      // id: {}, MySQL에서 id가 자동으로 생성된다.
      name: {
        type: DataTypes.STRING(20),
        allowNull: false,
      },
    },
    {
      // Hashtag Module에 대한 셋팅
      charset: "utf8mb4", // 한글 + 이모티콘
      collate: "utf8mb4_general_ci", // 한글 + 이모티콘 저장
    }
  );

  Hashtag.associate = (db) => {
    db.Hashtag.belongsToMany(db.Post, { through: "PostHashtag" }); // 하나의 해시태그에 여러개의 게시글 (M:N의 관계)
  };

  return Hashtag;
};

 

그리고 당연히 워크밴치에서는 게시글은 잘 들어갔지만, 해시태그 테이블은 아무것도 저장되지 않았죠.

게시글

해시태그

 

질문

지금 번역도 해보고 구글링도 해본 결과, 원인은 findOrCreate메소드를 사용하면서 전달해주는 where속성이 누락되었다고 하더라구요..

구글링을 해보니 첫번째 : where, 두번째 : 기본 키 (값), 세번째 : transaction 값을 넣어야된다고 나와있더라구요.

  • 궁금한게 강좌에서 설명하는 속성값과 지금 제가 검색해서 알게 된 넣어야되는 속성값이 다른이유가 있을까요 ?

  • 그리고 결국 결론은, 지금 현재 이 에러를 해결하기 위해서 기본값을 설정해주어야하는 부분인가요 ?

답변 1

답변을 작성해보세요.

0

엄청 허탈하실것 같은데요

where 오타났습니다. findOrCreate 내부에요

아름잉님의 프로필

아름잉

질문자

2023.07.19

네 .. 방금 확인했습니다.. 잠시 눈물 닦고 포효도 하고 다시 강좌 들으러 가겠습니다😭

아름잉님의 프로필

아름잉

질문자

2023.07.19

덕분에 findOrCrate 속성값을 알게 된 정보를 얻고 갑니다 껄껄,,