묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
timezone 관련
안녕하세요 선생님.질문이 있습니다! @CreateDateColumn({ name: 'mb_regs_tm', type: 'timestamp', comment: '등록일시', }) regs_tm: Date; @UpdateDateColumn({ name: 'mb_mod_tm', type: 'timestamp', nullable: true, comment: '수정일시', }) mod_tm: Date;위 데코레이션으로 만든 컬럼은 따로 시간을 지정해주지 않다보니 자동으로 UTC로 값이 설정되는데요.문제는 @Column({ name: 'mb_exp_tm', type: 'timestamp', nullable: true, comment: '만료일시', }) exp_tm: Date;이 컬럼의 경우 export function getExpirationDate(days: number): Date { const now = new Date(); return new Date(now.setDate(now.getDate() + days)); }위의 함수를 사용하여 데이터가 생성된 날로부터 90일을 더한 값으로 만료일을 설정하거든요.근데 mb_exp_tm 컬럼만 KST로 설정되고 나머지 mb_regs_tm, mb_mod_tm는 UTC로 데이터가 저장됩니다. https://github.com/typeorm/typeorm/issues/5841위 이슈에서도 제가 현재 고민하고 있는 부분에 대해 얘기하고 있지만 명확한 답은 아직 찾질 못해서요.혹시 위 문제에 대한 해결책을 들을 수 있을까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
특정 post의 특정 코맨트 조회 API 관련 질문
@Get(':commentId') getComment(@Param('commentId', ParseIntPipe) commentId: number) { return this.commentsService.getCommentById(commentId); }안녕하세요 코드팩토리님해당 강의 듣는중 CommentController의 getComment 메서드에서 분명 특정 post의 특정 comment를 가져와야할거같은데 보면 commentId로만 조회하는걸로 보여집니다.제가 이해하지 못하고 의도를 파악하지 못한건지 반대인지 확인이 필요해보입니다. 상기는 해당 문제되어 보여지는 코드입니다. 강의에서는 postman을 사용해 해당 엔드포인트로 요청하는 장면이있는데 postId에 152? 게시글ID 값을 넣어서 조회하는데 코드대로면 의미가 없어보입니다.감사합니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
[세션 10] FindOne 함수 이용해서 하나의 데이터만 찾기에서
http://localhost:3000/posts/:id 를 send하게되면NotFoundException()이 실행이 되야하는데 이런 에러가 나옵니다async getPostById(id: number) { const post = await this.postsRepository.findOne({ where: { id, }, }); if (!post) { throw new NotFoundException(); } return post; }잘 입력한 것 같은데 . 왜그런가요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
OneToOne Option OnDelete 작동
안녕하세요 코드팩토리님 NestJS에 관심이 생겨 최근 강의를 듣고 있습니다.OneToOne 에서 onDelete 설정을 했을 때 계속 profile이 null 값으로만 변경되는데 제 코드에 문제가 있는지 궁금합니다. 검토 한 번 부탁드려요. 감사합니다!!// user.entity.ts export class UserModel { // 자동으로 ID 생성 @PrimaryGeneratedColumn() id: number; @Column() email: string; @Column({ type: 'enum', enum: Role, default: Role.USER, }) role: Role; // 데이터가 생성되는 날짜와 시간이 자동으로 찍힌다. @CreateDateColumn() createdAt: Date; // 데이터가 업데이트되는 날짜와 시간이 자동으로 찍힌다. @UpdateDateColumn() updatedAt: Date; // 데이터가 업데이트 될 때마다 1씩 올라간다. // 처음 생성되면 값은 1이다. // save() 함수가 몇번 불렸는지 기억한다. @VersionColumn() version: number; @Column() @Generated('uuid') additionalId: string; ////////////// 이 부분 ///////////// @OneToOne(() => ProfileModel, (profile) => profile.user, { // find() 실행 할 때마다 항상 같이 가져올 relation을 정할 수 있다. eager: true, // 저장할 때 relation을 한번에 같이 저장 가능하게 한다. cascade: true, // null 값이 가능하게 한다. nullable: true, // on: ~했을 때 // 관계가 삭제 됐을 때 // no action => 아무것도 안함 // cascade => 참조하는 Row도 같이 삭제 // set null => 참조하는 Row에서 참조 id를 null로 변경 // set default => 기본 세팅으로 설정 (테이블의 기본 세팅) // restrict => 참조하고 있는 Row가 있는 경우 참조 당하는 Row 삭제 불가 onDelete: 'RESTRICT', }) profile: ProfileModel; ////////////// 이 부분 ///////////// @OneToMany(() => PostModel, (post) => post.author) posts: PostModel[]; } // app.controller.ts import { Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Role, UserModel } from './entity/user.entity'; import { Repository } from 'typeorm'; import { ProfileModel } from './entity/profile.entity'; import { PostModel } from './entity/post.entity'; import { TagModel } from './entity/tag.entity'; @Controller() export class AppController { constructor( @InjectRepository(UserModel) private readonly userRepository: Repository<UserModel>, @InjectRepository(ProfileModel) private readonly ProfileRepository: Repository<ProfileModel>, @InjectRepository(PostModel) private readonly PostRepository: Repository<PostModel>, @InjectRepository(TagModel) private readonly TagRepository: Repository<TagModel>, ) {} @Get('users') getUsers() { // OntToOne에 eager: true 설정을 하면 relations 옵션을 여기에서 넣어주지 않아도 된다. return this.userRepository.find({}); } @Delete('user/profile/:id') async deleteProfile(@Param('id') id: string) { await this.ProfileRepository.delete(+id); } @Post('user/profile') async createUserAndProfile() { const user = await this.userRepository.save({ email: 'asdf@naver.com', profile: { profileImg: 'asdf.jpg', }, }); // cascade: true 설정을 하면 relation을 한번에 같이 저장하게 되서 더 이상 두번 save 할 필요가 없음 // const profile = await this.ProfileRepository.save({ // profileImg: 'asdf.jpg', // user, // }); return user; } }
-
해결됨Real MySQL 시즌 1 - Part 1
[오타 제보] 선행 데이터를 기반으로 한 데이터 분석
안녕하세요~!강의에 오타가 있는 것 같아서 질문 드립니다.e2 서브쿼리에 user_id도 select 절에 포함되야 할 것 같아요!select sum(sign_up) as signed_up, sum(complete_purchase) as completed_purchase, (sum(complete_purchase) / sum(sign_up) * 100) as conversion_rate from ( -- 1월에 새로 가입한 유저 목록 select user_id, 1 as sign_up, min(created_at) as sign_up_time from user_events where event_type = 'SIGN_UP' and created_at >= '2024-01-01' and created_at < '2024-02-01' group by user_id ) e1 left join ( -- 처음 결제한 시점 정보 목록 select user_id, 1 as complete_purchase, min(created_at) as complete_purchase_time from user_events where event_type = 'COMPLETE_PURCHASE' group by user_id ) e2 on e2.user_id = e1.user_id and e2.complete_purchase_time >= e1.sign_up_time and e2.complete_purchase_time < date_add(e1.sign_up_time, interval 7 day);
-
미해결처음하는 파이썬 백엔드 FastAPI 입문 (FastAPI부터 비동기 SQLAlchemy까지) [풀스택 Part1-2]
터미널에서 uvicorn명령어 칠때 자동완성
자동완성 되시던데요. 어떤 확장프로그램쓰시는걸까요
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
basic, bearer 토큰 관련 문의
안녕하세요basic, bearer 토큰을 이미 범용적으로 널리 사용된다고 하셨는데 궁금한점이로그인할 때 id/pw 를 header 에 넣어서 보낸다고 하셨는데패킷을 탈취하면 너무 취약할 것 같아서요. 제가 웹개발자가 아니라 실무에선 실제로 어떻게 쓰는지 알고싶어서 질문남깁니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
debug 강의 질문입니다.
강의 내용처럼 그대로 따라 했을 때 다음과 같이 됩니다.1. 아래 사진 처럼 breakpoint 설정 시 빨간색이 아니라 빈원이 나옵니다. 실제 실행하였을 경우 break가 걸리긴 하는데 ts파일이 아닌 compile된 js 파일로 넘어갑니다. 인터넷 찾아보고 sourceMap 관련된거 같아서 tsconfig 파일에 sourceMap: true 넣고 launch.json에 sourceMaps: true 넣어봤는데도 변함이 없네요 어떤 부분을 확인해봐야할까요?
-
해결됨Real MySQL 시즌 1 - Part 1
2강. VARCHAR(255) 저장되는 데이터의 길이 정보 질문
안녕하세요. 2강을 수강하면서 궁금한 점이 있어 질문 글 남깁니다. VARCHAR(30) vs VARCHAR(255) 둘 중에서 데이터 타입을 선택할 때 실제 사용하는 길이만큼만 명시해 주는 게 메모리 사용 효율을 높일 수 있다고 말씀해주셨는데요.VARCHAR(30)와 VARCHAR(255) 모두 저장되는 데이터의 길이 정보를 1 바이트(0~255 표현 가능)로 저장하는 것이 맞는걸까요?강의 자료에 VARCHAR(30) vs VARCHAR(255) 차이를 설명할 때 '디스크 공간 효율 차이도 미미하게 존재(1바이트 vs 2바이트)'라고 적혀 있어 VARCHAR(255)에서 저장되는 데이터 길이 정보에 2바이트의 공간을 할당한다는 의미로 이해되어서요. 좋은 강의 감사합니다.
-
해결됨[7일완성]생각하는 데이터베이스모델링
쿼리 질문드립니다!
안녕하세요 선생님."26_학사관리시스템(SQL실습3)"에 있는 쿼리 중에 조인과 서브쿼리 중 대체적으로 어떤 방법이 성능에 더 좋은지 궁금해서 질문드립니다.두 가지 질의에 대해서 3가지 방법으로 조인과 서브쿼리를 섞어보았는데 조언 부탁드립니다.감사합니다. -- 교양엉어 과목을 수강 신청한 학생의 이름-- 1. JOIN 2번select s.student_namefrom student_course scJOIN student s on sc.student_id = s.student_idJOIN course c on sc.course_code = c.course_codewhere c.course_name = '교양 영어';-- 2. JOIN 1번, where 절에 subQuery 1번select s.student_namefrom student_course scJOIN student s on sc.student_id = s.student_idwhere course_code = (select course_codefrom coursewhere course_name = '교양 영어');-- 3. where 절에 subQuery 2번select s.student_namefrom student swhere s.student_id in (select student_id from student_coursewhere course_code = (select course_code from coursewhere course_name = '교양 영어' ));-- 가교수의 과목을 수강신청한 학생수를 출력-- 1. JOIN 2번select count(student_id) as cnt -- count(student_id) as cntfrom student_course scJOIN course c on sc.course_code = c.course_codeJOIN professor p on c.professor_code = p.professor_codewhere p.professor_name = '가교수';-- 2. JOIN 1번, WHERE 절에 subQuery 1번select count(sc.student_id) as cntfrom student_course scwhere course_code in (select c.course_code from course cJOIN professor p on c.professor_code = p.professor_code where p.professor_name = '가교수');-- 3. where 절에 subQuery 2번select count(sc.student_id) as cntfrom student_course scwhere sc.course_code in (select c.course_code from course cwhere professor_code = (select professor_code from professor pwhere professor_name = '가교수'));
-
해결됨Real MySQL 시즌 1 - Part 1
LIMIT, OFFSET을 사용하는 것과 범위 기반 방식의 성능 차이
안녕하세요. 강의 잘 듣고 있습니다. 제가 이해한바로는 LIMIT, OFFSET은 앞에서부터 data를 순차적으로 읽기때문에 성능 상 좋지 않고 이를 개선하기 위해 범위 기반 방식을 사용한다고 이해하였습니다.범위 기반 방식은 직접 ID 값을 지정 해주는 방식이며, id 기반으로 5000단위로 조회한다고 가정하면1회차: select * from users where id > 0 AND id <= 50002회차: select * from users where id > 5000 AND id <= 1000위와 같이 구현될 것으로 예상됩니다.관련해서 궁금한 점이 생겼는데요. 결국 두번째 쿼리를 실행 시 5000보다 큰 id를 찾는 과정에 시간이 소요될 것으로 예상되는데요, id가 index로 지정되어있어 LIMIT, OFFSET 방식보다 빠르게 찾을 수 있는 것인가요??LIMIT, OFFSET 방식 사용 시 어떤 컬럼이 index로 지정되어있는지와 상관없이 무조건 순차 탐색이 일어나는 것이고 범위 기반으로 조회 시 index로 서치하기때문에 더 빠르게 시작점을 탐색할 수 있다고 이해하면 될까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
코드팩토리님, 강의 질문 있습니다.
패스트 캠퍼스에서 올린 강의에 대한 질문을 어디에 올려할지 모르겠어서 여기에 남깁니다.아키텍처 대통합은 언제 올라나요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
JWT refresh 에대해 질문이 있습니다.
jwt refresh 토큰은 access 토큰이 만료되었을때 재발급을 위한 토큰이라고 알고있는데요보통 refresh 는 시간을 길게주고 access 토큰은 짧게 줘서 관리하는것으로 알고있습니다.근데 강의를 다듣고 정리하는데 refresh에 대해 궁금증이 생겼습니다. 강의에서는 따로 DB에 저장안한거 같은데 DB에 저장하지않고 관리하는거라면 refresh도 만료시간이 있을텐데 이걸 어떻게 관리하는것인지요?http only cookie로 클라이언트에 건내줘서 클라이언트가 만료될때마다 서버쪽으로 던지는것인지아니면 DB에 저장해서 관리하는것인지 궁금합니다. 어떤것이 정답이라고 할수 없겠지만보통 실무에서는 어떻게 관리할까요
-
해결됨Real MySQL 시즌 1 - Part 2
unique index가 걸린 상황에서 s-lock, x-lock 질문
안녕하세요?먼저 좋은 강의 감사합니다. 7:50쯤 unique 제약조건이 걸린 상황에서 deadlock이 발생하는 경우에 질문이 있어서 글 남깁니다. 말씀주신 시나리오는unique index가 걸린 컬럼이 delete가 수행되면서, 동시에 insert into 구문이 들어오는 상황으로 말씀주셨는데요. unique index는 s-lock을 꼭 필요로 한다면,delete가 선행되지 않는 상황에서도 deadlock이 발생해야되는거 아닌가? 싶습니다. 상상하는 예시는 다음과 같습니다.tx-1 : begin; insert into tab(pk) values(2) (index 2 또는 그 범위에 s-lock) tx-2 : begin; insert into tab(pk) values(2) (index 2 또는 그 범위에 s-lock)tx-1 : commit; -> index 2에 x-lock을 잡으려고 하지만 tx-2가 s-lock을 잡고 있어서 잡을 수 없음 하지만, 실제로 테스트 해보았을 때는tx-1이 commit시에 정상적으로 insert 되고, tx-2는 duplicated key 오류를 반환합니다. 왜 이런지 알 수 있을까요?감사합니다 😃 다시 한 번 생각해보니, tx-1은 pk=2 가 없기 때문에 insert 후 x-lock으로 전환하고, tx-2는 x-lock으로 인해 lock_wait인 것 같습니다. 혹시 맞을까요?delete 가 선행된 경우는 이미 있는 레코드에 tx-1,2가 s-lock이을 잡으면서 delete가 commit된 시점에 tx-1,2가 x-lock을 획득하려는데서 dead lock이 발생하는 것이고요
-
미해결[7일완성]생각하는 데이터베이스모델링
계산 로직을 Java 단이 아닌 쿼리문에서 하신 이유가 궁금합니다.
select sum(cp.quantity * p.price) as totalAmount from customer_product cp inner join product p on cp.product_number = p.product_number where cp.customer_id = #{customer_id}장바구니에 들어있는 상품의 개수와 가격을 곱한 금액의 총합을 구하는 로직을 17:50 쯤에 보여주셨습니다.DB에 Connection하는 비용을 고려하면 계산 로직은 Java에서 처리하는 게 더 빠르지 않을까 생각했습니다. 실무에서 많이 사용한다던가, 아니면 더 좋은 방법이라고 생각하셨던 이유가 있었을까요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
http Exception filter 적용
http Exception filter 적용이 안됩니다. import { ArgumentsHost, Catch, ExceptionFilter, HttpException, } from '@nestjs/common'; import { Response } from 'express'; @Catch(HttpException) export class HttpExceptionFilter implements ExceptionFilter { catch(exception: HttpException, host: ArgumentsHost) { console.log('exception', exception); const ctx = host.switchToHttp(); const response = ctx.getResponse<Response>(); const status = exception.getStatus(); const err = exception.getResponse() as | string | { error: string; statusCode: number; message: string | string[] }; console.log('err', err); if (typeof err !== 'string' && err.error === 'Bad Request') { return response.status(status).json({ ok: false, statusCode: status, data: err.message, }); } response.status(status).json({ ok: false, statusCode: status, data: err, }); } } 위처럼 하고난뒤에 main.ts 파일에 app.useGlobalFilters(new HttpExceptionFilter());추가했는데 위처럼 에러 포맷이 안나옵니다. const foundUser = await this.dataSource.getRepository(UserEntity).findOne({ where: { id } }); if (!foundUser) { console.log('User not found'); throw new BadRequestException('User not found'); }{ "response": { "message": "User not found", "error": "Bad Request", "statusCode": 400 }, "status": 400, "options": {}, "message": "User not found", "name": "BadRequestException"}
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
one to many mapping에 관하여
oneToMany mapping와 manyToOne mapping에서 users.tntity.ts에 있는 posts항목에 의문이 생겨 질문 드립니다. PostModel list로 되어있는데 DB table은 2dimension이 되지 않는다고 하신것 같아서요 혹시 내부는 어떻게 구현이 되어 있는지 알 수 있나요
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
BearerTokenGuard 구현해보기
코드팩토리 디스코드에 질문하면 더욱 빠르게 질문을 받아 볼 수 있습니다![코드팩토리 디스코드]https://bit.ly/3HzRzUM 토큰이 없다고 듭니다. 토큰값이 담기는건 확인되는데포스트맨 authorization : Bearer refreshToken 넣어보면 토큰이 없습니다. 401 떠서 다시 계속 해보는데 못찾겠습니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
nestjs routing 질문있습니다.
controller에서 /test/:id라는 숫자를 받는 get 엔드포인트가 있고/test/info라는 정보를 주는 routing을 만들고 싶은데 test/info라고 호출하면 test/:id로 들어가더라구요 이걸 해결할 수 있는 방법이 있을까요?
-
해결됨Real MySQL 시즌 1 - Part 1
MySQL Where절 내 조건의 순서
안녕하세요. MySQL 사용에 있어 Where절 내 조건의 순서가 쿼리 성능에 영향을 미치는지 여쭙고자 문의드립니다. 기본적으로는 옵티마이저가 쿼리를 최적화하기 때문에 Where절의 순서가 중요하지 않은 것으로 알고 있는데, DBMS에 따라 통계정보를 활용하는 데 있어 차이가 있다는 이야기를 들은 바 있어 호기심에 여쭤봅니다. (MySQL 공식문서에는 관련된 내용을 못 찾겠네요..)