-
Notifications
You must be signed in to change notification settings - Fork 8
Sequelize graphQL apollo
hos101010 edited this page Dec 11, 2019
·
1 revision
- 초기 설정 (user - friend)
//User
Users.hasMany(models.Friends);
//Friend
Friends.belongsTo(models.Users, { as: 'p_friend_id', foreignkey: 'id' });
Friends.belongsTo(models.Users, { as: 's_friend_id', foreignkey: 'id' });
-
문제 발생
- user를 통해 friend를 찾는 쿼리를 날리면 p_friend_idId 컬럼을 탐색하면서 에러
-
원인
- 외래키는 target 모델의 이름 + target 모델의 주요 키 이름 으로 자동으로 이름 설정이 됨
- p_friend_id(target모델의 이름) + Id(user의 주요키)가 되어 p_friend_idId가 생성됨
- sequelize는 CamelCase로 자동으로 설정되어있음
- underscored: true로 세팅을 해주면 snake_case가 됨
- 하지만 우리는 createAt을 살리고 싶었고, 전체 코드 규칙을 CamelCase로 정했기 때문에 snake_case는 원하지 않음
- hasMany에서 어떤 것과 매칭해줄지 명시하지 않았음
- sequelize에서는 foreignKey 옵션이 정의되지 않으면 새로운 컬럼을 생성함
- belongsTo에서 명시했기에 알아서 해줄줄 알았지만 belongsTo와 hasMany는 별개의 것이였음 (하단에 설명)
- 외래키는 target 모델의 이름 + target 모델의 주요 키 이름 으로 자동으로 이름 설정이 됨
-
해결
- sourceKey와 targetKey를 이용한 둘 사이 sync 맞춤
- 모든 컬럼명 camelCase로 변경
//Users
Users.hasMany(models.Friends, { foreignKey: 'pFriendId', sourceKey: 'id' });
Users.hasMany(models.Friends, { foreignKey: 'sFriendId', sourceKey: 'id' });
//Friends
Friends.belongsTo(models.Users, {
foreignKey: 'pFriendId',
targetKey: 'id',
});
Friends.belongsTo(models.Users, {
foreignKey: 'sFriendId',
targetKey: 'id',
});
hasMany를 쓰면 users가 friends에는 접근이 가능하나 friends가 users에는 접근 못함 belongsTo는 그 반대 서로 접근해야하는 경우에는 has-와 belongsTo 둘 다 써줘야함
- Mutation
const [findFriendsFunc] = useMutation(findFriends);
- Query
const { data, loading, error } = useQuery(findFriends);
-
오해..
useMutation에서는 함수를 반환하고 useQuery에서는 data를 반환하는구나-
내가 원할 때 언제든지 데이터 읽고 싶으면 useMutation으로 함수 갖다 써야겠다=> 완전히 오해해버림...
-
mutation은 자체적으로 lock을 걸어주기 때문에 CRUD할 때 사용해야함!
-
단순한 read 작업에서는 mutation을 쓰면 필요없는 lock을 걸어주기 때문에 성능이 하락 => query를 사용!
- 컴포넌트가 rerendering되어도 apollo 자체에서 캐싱해줌
- 캐싱을 원하지 않는다면?
- apollo 작업 전체에 대해 캐싱을 막자
- refetch를 이용해 해당 쿼리만 다시 data를 받아오자
- 상황 : sequelize에서 includes를 이용해 Friend table의 id로 user를 join하는 경우
- 문제 : friend table에는 userId를 참조하는게 두개가 있음 -> 명시 안해주면 에러 발생
- 해결 : 'as'로 어떤걸 가리키는지 나타내줌
///graphql resolver
const deletedColumns = await Friends.findAll({
include: [
{
model: Users,
as: 'sFriend', //here
where: { [Op.or]: [{ nickname: nickname }, { id: req.user.id }] },
},
{
model: Users,
as: 'pFriend', //here
where: { [Op.or]: [{ nickname: nickname }, { id: req.user.id }] },
},
],
});
//sequelize model
Friends.belongsTo(models.Users, {
foreignKey: 'pFriendId',
as: 'pFriend', //here
targetKey: 'id',
});
Friends.belongsTo(models.Users, {
foreignKey: 'sFriendId',
as: 'sFriend', //here
targetKey: 'id',
});
Users.hasMany(models.BeforeFriends, {
foreignKey: 'pFriendId',
sourceKey: 'id', //here
as: 'pFriend',
});
Users.hasMany(models.BeforeFriends, {
foreignKey: 'sFriendId',
sourceKey: 'id', //here
as: 'sFriend',
});
- 그래서 테이블 파일 하나만 대문자임ㅎ
- 터미널에서 mv로 바꿔야함