묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결처음하는 파이썬 백엔드 FastAPI 입문 (FastAPI부터 비동기 SQLAlchemy까지) [풀스택 Part1-2]
연동된 강의안과 수업에서 하는 강의안이 달라요
인강에서 보여주는 강의안과 드라이브에서 받아보는 강의안에 다른데.. 갱신된 강의안은 어디서 얻을 수 있나요?
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
cascade 자식이 부모삭제가 맞는건가요??
안녕하세요. 지금 typeORM에서 cascade를 보고있는데fk를 삭제하면 pk가 삭제하는게 일반적인 동작인지가 궁금합니다. User 엔티티에서 onDelete : "cascade"로 설정해두었고삭제는 부모에서 > 자식으로 연결되는 것으로 알고 있습니다. 근데 ProfileModel의 레코드가 삭제되도 Join한 레코드도 삭제되는데자식 > 부모로 삭제가 전파되는게 맞는건지 혼란이옵니다.강의에서도 profile을삭제하니 User레코드가 날아가버리는데 이 현상이 이해 되질않습니다. 부모>자식 cascade를 인한 연쇄 삭제 or update자삭>부모 cascade를 인한 삭제 불가 이게 기존 제 개념인데 제가 잘못알고있던건가 찾아보아도 정보가 좀 엉켜있네요.. typeORM만의 기능인지 SET NULL로 방지해야 하는건지 궁금합니다.
-
해결됨Real MySQL 시즌 1 - Part 1
ep11) Prepared Statement에서 질문
안녕하세요 강사님Client Side PreparedStatement 는 어떻게 SQL Injection을 막을 수 있다는게? 에 set하기전에 application에서 체크해서 막는다는의미인가요?
-
미해결처음하는 파이썬 백엔드 FastAPI 입문 (FastAPI부터 비동기 SQLAlchemy까지) [풀스택 Part1-2]
mySQL과 fastAPI가 연동이 안됨
mysql 과 mysql workbench를 설치하고 접속하려는데 안돼서 고생하고 있습니다.코드는 아래와 같고'code'from fastapi import FastAPI, Dependsfrom sqlalchemy.orm import Sessionfrom sqlalchemy import Column, Integer, String, create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom pydantic import BaseModelDATABASE_URL = "mysql+pymysql://newjeans:@gaius2127@localhost:3306/db_name"engine = create_engine(DATABASE_URL)Base = declarative_base()class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True, index=True) username = Column(String(50), unique=True, index=True) email = Column(String(120))class UserCreate(BaseModel): username: str email: strdef get_db(): db = Session(bind=engine) try: yield db finally: db.close()Base.metadata.create_all(bind=engine)app = FastAPI()@app.get("/")def read_root(): return {"message": "Now, tackle with mySQL"}@app.post("/users/")def create_user(user: UserCreate, db: Session = Depends(get_db)): new_user = User(username=user.username, email=user.email) db.add(new_user) db.commit() db.refresh(new_user) return {"id": new_user.id, "username": new_user.username, "email": new_user.email} 터미널에 메세지는 PS C:\wonnho\fastapi> python -m uvicorn main:app --reloadINFO: Will watch for changes in these directories: ['C:\\wonnho\\fastapi']INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)INFO: Started reloader process [20636] using StatReloadProcess SpawnProcess-1:Traceback (most recent call last): File "C:\Python312\Lib\site-packages\pymysql\connections.py", line 644, in connect sock = socket.create_connection( ^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python312\Lib\socket.py", line 828, in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python312\Lib\socket.py", line 963, in getaddrinfo for res in _socket.getaddrinfo(host, port, family, type, proto, flags): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^socket.gaierror: [Errno 11003] getaddrinfo failedDuring handling of the above exception, another exception occurred:Traceback (most recent call last): File "C:\Python312\Lib\site-packages\sqlalchemy\engine\base.py", line 3280, in wrappool_connect return fn() ^^^^ 중간 생략..... File "C:\Python312\Lib\site-packages\pymysql\connections.py", line 358, in init self.connect() File "C:\Python312\Lib\site-packages\pymysql\connections.py", line 711, in connect raise excsqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'gaius2127@localhost' ([Errno 11003] getaddrinfo failed)")(Background on this error at: https://sqlalche.me/e/14/e3q8)아이디와 패스워드가 문제인거 같은데 뭐가 문제인지 모르겠네요. 륀튼에게 물어보고 제미나이도 물어봤는데 해결이 안되어 힌트라도 얻을려고 질문합니다.위에 newjeans라는 아이디가 있음.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
스웨거 문서에 Basic, Bearer를 적용하는 방법에 대해 질문 드립니다.
AccessToken, RefreshToken 강의 내용을 모두 마친 후에 스웨거 문서 작성 방법에 대해 궁금한 점이 있어 질문 드립니다. @Headers()를 사용하여 rawToken 값을 전달하는 경우 스웨거 문서에서는 다음과 같이 @ApiBasicAuth('basic'), @ApiBearerAuth('bearer') 형식을 작성을 해야하는지 질문 드립니다. import { Body, Controller, Headers, Post, UseGuards } from '@nestjs/common'; import { AuthFacade } from '@root/resource/auth/auth.facade'; import { BasicTokenGuard } from '@root/common/guard/basic-token.guard'; import { RefreshTokenGuard } from '@root/common/guard/bearer-token.guard'; import { IsPublic } from '@root/common/decorator/is-public.decorator'; import { ApiBasicAuth, ApiBearerAuth, ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { AccessAndRefreshTokenResponse, AccessTokenResponse, RefreshTokenResponse, } from '@root/resource/auth/dto/response/token-response.dto'; @ApiTags('Auth API') @Controller('v1/auth') export class AuthController { constructor(private readonly authFacade: AuthFacade) {} @ApiOperation({ summary: '로그인', description: 'Authorization Basic 이메일:비밀번호 방식으로 로그인합니다.' }) @ApiBasicAuth('basic') @ApiOkResponse({ type: AccessAndRefreshTokenResponse }) @IsPublic() @UseGuards(BasicTokenGuard) @Post('login') async login(@Headers('authorization') rawToken: string) { return await this.authFacade.loginWithEmail(rawToken); } @ApiOperation({ summary: '회원가입', description: '이메일, 비밀번호로 회원가입을 진행합니다.' }) @ApiOkResponse({ type: AccessAndRefreshTokenResponse }) @IsPublic() @Post('register') async register(@Body('email') email: string, @Body('password') password: string) { return await this.authFacade.registerWithEmail(email, password); } @ApiOperation({ summary: 'AccessToken 갱신', description: 'RefreshToken으로 AccessToken을 갱신합니다.' }) @ApiBearerAuth('bearer') @ApiOkResponse({ type: AccessTokenResponse }) @IsPublic() @UseGuards(RefreshTokenGuard) @Post('token/access') generateAccessToken(@Headers('authorization') rawToken: string) { return this.authFacade.generateAccessToken(rawToken); } @ApiOperation({ summary: 'RefreshToken 갱신', description: 'RefreshToken으로 RefreshToken을 갱신합니다.' }) @ApiBearerAuth('bearer') @ApiOkResponse({ type: RefreshTokenResponse }) @IsPublic() @UseGuards(RefreshTokenGuard) @Post('token/refresh') generateRefreshToken(@Headers('authorization') rawToken: string) { return this.authFacade.generateRefreshToken(rawToken); } }
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
저는 강의와 다르게 prisma를 사용하고 있는데
ConfigModule의 envFilePath에 '.env.development' 을 줬음에도 불구하고 Nest.js가 계속 .env 의 환경변수를 참조하는 현상이 발생하고 있습니다. NODE_ENV=development도 줬구요. 제 생각엔 Prisma가 .env를 참조하기 때문에 해당 설정이 무시되는 거 같은데 어떻게 해결하면 좋을까요? 아무리 검색해도 명쾌한 해결법이 안나와서 이렇게 질문드립니다 ㅠㅠ
-
해결됨Real MySQL 시즌 1 - Part 1
7)select for update 강의에서 질문
안녕하세요 강사님 gpt o1에게 물어보다가 질문이 생겼습니다.read committed 상태일 때 select for update를 쓰면 해당 statement가 끝나면 lock이 풀린다는데 이는 잘못된거지요?
-
해결됨PZM기반 실무중심 백엔드 부트캠프(프리트레이닝)
rest api json 객체 한글 깨짐 현상
안녕하세요~ 선생님 강의 정말 재미있게 듣고 있습니다. 49강 강의를 듣는 중에 restful api json 객체 한글 깨짐 현상이 있습니다. 혹시 chrome 문제였나 싶어 postman 으로도 띄워봤지만 여전합니다.ㅠㅠㅠ 구글 찾아가며 해결해보려고 했지만 잘 해결되지 않습니다. // http://localhost:8081/myweb/rest @RequestMapping("/rest" ) public List<String> rest(HttpServletResponse response){ response.setCharacterEncoding("UTF-8"); List<String> list=new ArrayList<>(); list.add("스프링 프레임워크"); list.add("잘 하면"); list.add("된다"); System.out.println("Returning list: " + list); return list; // rest.jsp <-- 뷰를 만들면 된다.(X) : JSON -> [{ key:value, , ,}.{ },{ }] }System.out.println("Returning list: " + list);이 부분 콘솔에 찍힌 값도 Returning list: [�뒪�봽留� �봽�젅�엫�썙�겕, �옒 �븯硫�, �맂�떎]이렇게 나옵니다. 수정:// http://localhost:8081/myweb/rest @RequestMapping("/rest" ) public List<String> rest(){ List<String> list=new ArrayList<>(); list.add("스프링 프레임워크"); list.add("잘 하면"); list.add("된다"); System.out.println("Returning list: " + list); System.out.println("안녕"); return list; // rest.jsp <-- 뷰를 만들면 된다.(X) : JSON -> [{ key:value, , ,}.{ },{ }] }System.out.println("안녕");이 부분도 깨져서 나와용. ㅠㅠㅠㅠㅠ감사합니다~package com.example.controller;import com.example.entity.Book;import com.example.repository.BookMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import java.util.ArrayList;import java.util.List;@RestControllerpublic class SpringRestController { // http://localhost:8081/myweb/rest@RequestMapping("/rest")public List<String> rest(){List<String> list=new ArrayList<>();list.add("스프링 프레임워크");list.add("잘 하면");list.add("된다");return list; // rest.jsp <-- 뷰를 만들면 된다.(X) : JSON -> [{ key:value, , ,}.{ },{ }]} }
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
쿼리러너 대신 @Transactional
안녕하세요.쿼리러너대신 @Transactional을 사용하면 되지않나요?사용안하신 이유가 있나요? nest에서 지원을 안하는것인지?스프링쪽과 같이 공부하다보니 궁금한점이 생겨서 질문드립니다.
-
해결됨Real MySQL 시즌 1 - Part 1
12강. LEFT JOIN 사용 방법 준수 5:42
안녕하세요 강의 잘 듣고 있습니다.강의 내용 중 오른쪽 쿼리에서 LEFT JOIN이 불필요하게 들어가서 쿼리들에서 LEFT JOIN을 제거하는게 쿼리 성능에 도움이 된다고 하셨는데요.LEFT JOIN 대신 INNER JOIN을 사용하는 것으로 이해하는게 맞을까요? 제거하라하면 JOIN 자체를 제거하라는 의미인지 헷갈려서 질문 남기게 되었습니다. 감사합니다.
-
해결됨Real MySQL 시즌 1 - Part 1
6강. Top N 데이터 조회와 관련해 질문있습니다.
안녕하세요. 강의 마지막에 카테고리별 조회수가 가장 높은 3개 기사를 추출 하는 쿼리 소개해 주셨는데요. 관련해서 질문 있습니다. Q1) 만약 categories 테이블에 id가 1,2,3인 데이터가 있다면 SELECT FROM WHERE category_id = 1 ORDER BY LIMIT 3SELECT FROM WHERE category_id = 2 ORDER BY LIMIT 3SELECT FROM WHERE category_id = 3 ORDER BY LIMIT 3이렇게 3번의 서브쿼리가 실행되고 각 결과를 전부 Union해서 최종 결과를 반환하게 되는건가요?Q2) LIMIT 3을 제거했을 때 내림차순 정렬이 안된 상태로 데이터가 반환되는데요. 그 이유가 뭔지 알 수 있을까요?
-
미해결내 마음대로 되지 않는 백엔드 테스트코드 - 희망편 & 현실편
테스트 데이터 관련 질문입니다.
게시글과 게시글 카테고리가 존재해야만 댓글을 작성할 수 있는 구조에서, 다음과 같은 시나리오를 테스트하고자 합니다.사용자가 댓글을 10개 작성하면 뱃지가 발급되는 시나리오를 테스트하려고 합니다.댓글을 작성하려면 게시글과 게시글 카테고리가 먼저 저장되어 있어야 하며, 댓글에는 post_id가, 게시글에는 post_category_id가 각각 존재합니다.이 상황에서 다음 질문이 있습니다: 댓글에 있는 post_id와 게시글에 있는 post_category_id를 nullable 하게 설정해도 괜찮을까요?
-
해결됨Real MySQL 시즌 1 - Part 1
5강에서 사례로 언급하신 DETERMINISTIC 예제에 대해 질문있습니다.
5강 2분50초쯤에 '사용자의 수를 가져오는 함수'를 예시로 설명해 주셨는데요.- 이 Stored Function이 실행되는 순간에도 사용자의 가입은 계속된다.- 그로 인해 이 Stored Function은 호출할 때마다 결과값이 달라질 수도 있다.- 하지만 이러한 사용자 테이블의 레코드가 달라지는 것도 입력이 달라지는 것이라고 생각하기 때문에 MySQL서버에서 SELECT를 포함해서 하나의 Statement는 반드시 시작 시점의 스냅샷을 보도록 구현되어 있다.- 그래서 MySQL서버에서 실행되는 쿼리 문장 하나는 동일한 데이터 상태를 보게 된다.- 따라서 하나의 문장 내에서는 Stored Function이 여러번 호출되더라도 테이블의 데이터는 해당 시점의 스냅샷을 보기 때문에 함수의 인자만 동일하다면 입력이 달라지지 않는 것으로 본다.Q) DETERMINISTIC으로 정의된 함수에 대해서 스냅샷을 바라보도록 설정돼 있고, 이로 인해 함수가 참조하는 데이터(인자)가 변경돼도 그 외 나머지 입력값이 동일하다면 동일한 결과값을 반환하게 된다는 내용이 맞을까요?
-
해결됨Real MySQL 시즌 1 - Part 1
deternmistic 질문
안녕하세요deterministic 관련해서 궁금증이 있어 질문드립니다. 그럼 mysql stroed function을 생성할때 무조건 deterministic 으로 생성을 해야하는지요??예를들면, 함수 내에는 파라미터값을 받아서 select 결과값을 도출하는 가령, id값등등 있다고 가정하겠습니다. 그럼 select * from test where 함수('value') 등으로 넣어서 값을 도출받아 where 조건에 걸수있다고 가정해보면non deterministic 일 경우 fullscan을 탈거같은데요. 결론적으로 , 모든 함수를 전부 deterministic 으로 명시를 해줄경우 단점이 무엇인가요?? 감사합니다.
-
미해결Real MySQL 시즌 1 - Part 1
1강 CHAR타입에 대해 질문드립니다
안녕하세요. 우선 이렇게 좋은 강의 해주셔서 감사합니다. 강의를 듣다가 궁금한 부분이 있어 질문드립니다.Q1) 10:00분 경에 "CHAR여도 utf8mb4같은 가변길이 캐릭터 셋을 사용하면 때로는 예약된 빈 공간이 없을 수 있다"라고 말씀해 주셨는데요. 제가 강의를 듣고 이해하기로는 '1~4byte값을 가질 수 있다는 가변길이 캐릭터 셋' 성질 때문이 아니라 '문자 하나당 크기가 1byte를 초과했기 때문에' 예약된 빈 공간이 없어지는 걸로 생각했습니다. 즉, 가변길이 캐릭터 셋인 utf8mb4가 아닌 하나당 크기가 3byte인 어떤 고정길이 캐릭터 셋을 이용하더라도 동일하게 예약된 빈 공간이 없을꺼 같은데 혹시 제가 이해한게 맞을까요?Q2) 마지막 내용 정리하시는 부분에서 "인덱스된 컬럼이라면 CHAR가 효율적일 가능성이 더 높다"고 말씀해 주셨는데 어떤 이유로 인덱스된 컬럼에 CHAR가 더 좋을 가능성이 높은건지 알려주실 수 있으실까요?
-
미해결견고한 결제 시스템 구축
동시성 제어 (optimistic locking) 재시도 부분 질문 드립니다.
동시성 제어를 optimistic 방식으로 구현을 하시고 retry 를 직접 구현하셨느데요- 혹시 직접 구현하지 않고스프링 @Retryable 을 이용안하신 이유가 있으실까요? @Retryable을 하면 더 간단하게 재처리가 가능할것 같아서요~!
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
serivice, controller에서 의존성 주입시 순서보장은 어떻게 유지되나요?
@Injectable() export class AuthService { constructor( private readonly jwrService: JwtService, private readonly userService: UsersService, private readonly configService: ConfigService, ) {} class에서 constructor로 주입받은 의존성을 가져올때 key, value 형식이 아닌 순서대로 가져오는데 어떻게 첫번째에 무슨 의존성이 오는지 확신할 수 있게 되는건가요?단연한듯이 타입을 지정하고 내가 원하는 서비스를 꺼내오거나 레포지토리를 꺼내오는데 그 아래 어떤 바탕이 있는지 궁금합니다.
-
미해결견고한 결제 시스템 구축
결제 복구의 세부 과정을 병렬로 처리한 이유가 궁금합니다
안녕하십니까 여정민 강사님! 강의 도중 궁금한 점이 있어 질문 드리고자 합니다. 질문은 12:32 초의 코드를 보면package com.example.paymentservice3.payment.application.service import com.example.paymentservice3.payment.application.port.`in`.PaymentConfirmCommand import com.example.paymentservice3.payment.application.port.`in`.PaymentRecoveryUseCase import com.example.paymentservice3.payment.application.port.out.* import org.springframework.scheduling.annotation.Scheduled import reactor.core.scheduler.Schedulers import java.util.concurrent.TimeUnit class PaymentRecoveryService ( private val loadPendingPaymentPort: LoadPendingPaymentPort, //결제 처리가 완료되지 않은 상태의 결제를 조회 하기 위해 private val paymentValidationPort: PaymentValidationPort, //결제 유효성 검사 private val paymentExecutorPort: PaymentExecutorPort, //결제 승인 요청 private val paymentStatusUpdatePort: PaymentStatusUpdatePort //결제 상태 업데이트 ) : PaymentRecoveryUseCase { @Scheduled(fixedDelay = 180, timeUnit = TimeUnit.SECONDS) override fun recovery() { loadPendingPaymentPort.getPendingPayments() .map { PaymentConfirmCommand( paymentKey = it.paymentKey, orderId = it.orderId, amount = it.totalAmount() ) } .parallel(2) .runOn(Schedulers.parallel()) .flatMap { paymentValidationPort.isValid(it.orderId, it.paymentKey).thenReturn(it) } .flatMap { paymentExecutorPort.execute(it) } .flatMap { paymentStatusUpdatePort.updatePaymentStatus(PaymentStatusUpdateCommand()) } } }위와 같이 작성되어있는데 여기서결제 유효성 검사결제 승인 요청결제 상태 업데이트위 3가지 기능 수행을 병렬로 처리한 이유가 궁금합니다.강의에서 언급된 이유로는 "각 작업 간의 수행 순서가 중요하지 않은 작업들은 병렬로 처리하여 전체 처리 시간을 단축" 이라고 말씀하셨습니다. 제가 생각했을 때는 유효성 검사에 성공하면 결제 승인을 요청하고 결제 승인 요청에 대한 결과를 바탕으로 결제 상태 업데이트가 수행이 되어야 한다고 생각되어 병렬처리를 하는 부분에 있어 타당함을 잘 모르겠습니다. 제 짧은 견해로는 결제 유효성 검사결제 승인 요청결제 상태 업데이트위 순서를 지켜 수행되어야 한다고 판단하였습니다. 이 부분에 대해서 강사님의 생각이 궁금합니다. p.s. 좋은 강의를 제공해주셔서 감사합니다. 여태 수강한 강의 내용들이 모두 새로워 덕분에 공부할 부분을 많이 찾게 되어 감사드립니다. 앞으로도 좋은 강의를 만들어주시면 많은 도움이 될 것 같습니다 화이팅!
-
해결됨Real MySQL 시즌 1 - Part 2
시퀸셜하게 증가하지 않는 PK의 insert성능도 문제가 있을까요?
좋은 강의 제공해주셔서 감사합니다!강의를 듣다보니 의문점이 하나 생겼는데요. 에피소드 14의 시퀸셜하지 않은 UUID사용시 범위 검색의 조회 효율성 문제를 언급해주셨는데요 데이터 삽입시 인덱스가 리밸런싱되거나 리프노드의 실제 데이터 위치가 이동하는 문제가 발생할수도 있을까요?
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
auth/token/access, auth/token/refresh 엔드포인트에 대한 Guard 적용
현재 듣고 있는 강의 부분은 Guard chapter에서 basic, bearer guard를 적용하는 부분입니다. @Injectable() export class BearerTokenGuard implements CanActivate { constructor( private readonly authService: AuthService, private readonly usersService: UsersService, ) {} async canActivate(context: ExecutionContext): Promise<boolean> { const req = context.switchToHttp().getRequest(); const rawToken = req.headers['authorization']; if (!rawToken) { throw new UnauthorizedException('토큰이 없음'); } const token = this.authService.extractTokenFromHeader(rawToken, true); const result = await this.authService.verifyToken(token); // payload 반환 /** * req 객체에 넣을 정보 * 1) 사용자 정보 - user 객체 자체 * 2) token - token * 3) tokenType - access | refresh */ const user = await this.usersService.getUserByEmail(result.email); req.user = user; req.token = token; req.tokenType = result.type; return true; } } 제 개인적인 생각으로는 적어도 제목에 적힌 두 엔드포인트에 대해서는 현재의 BearerTokenGuard를 적용하는 것이 굳이 라는 생각이 듭니다. refreshToken을 이용하여 새로운 토큰을 발급받는 역할을 하는 두 엔드포인트에 대해 다른 줄은 다 문제가 크게 없다고 생각하지만 req.user = user;로 굳이 요청에 user 객체를 붙이는 것은 굳이라는 생각이 듭니다. 제 낮은 식견으로는 위 두 엔드포인트에 대한 guard는 또 따로 만들어야 한다고 생각이 드는데 강사님 생각이 궁금합니다.