일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- conda base 기본 설정
- conda base 활성화
- 오블완
- 려려
- 3000 port kill
- 티스토리챌린지
- conda 기초 설정
- conda 가상환경 설정 오류
- time wait port kill
- window netstat time wait 제거
- 실행중인 포트 죽이기
- Today
- Total
모도리는 공부중
2023.11. 개발 궁금증 링크 일기 본문
[ 목차 ]
개인 공부 관련
JavaScript
스프레드 문법
NestJS 강의를 듣고 있는데 현재는 db가 아닌 메모리에 탑재해놓고 crud를 진행중이다. 그러던 중 아래 코드와 같이 스프레드 문법을 이용하면 기존 내용을 복사해와서 기존 내용 위에 변경된 일부 내용만 덮어씌우기가 가능한 것처럼 설명하는데 뭔가 잘 이해가 안 가서 gpt한테도 물어보고 추가 검색도 진행해봤다.
update(id: number, data) {
const index = this.getBoardId(id);
if (index > -1) {
this.boards[index] = {
...this.boards[index],
...data
}
}
}
gpt 설명
좋아, 좀 더 자세히 설명해보겠어. 스프레드 문법(`...`)은 객체나 배열에서 값을 복사하거나 합칠 때 사용되는 문법이에요. 여기서 `this.boards[index]`는 배열 `this.boards`에서 `index` 위치에 있는 객체를 나타냅니다. 그리고 `...this.boards[index]`는 해당 객체의 속성들을 복사하는 역할을 합니다. 즉, 기존 객체를 변경하지 않고 그 속성들을 새로운 객체로 복사하는 거죠. 그리고 `...data`는 전달된 `data` 객체의 속성들을 복사합니다. 여기서는 `data` 객체가 새로운 값을 포함하고 있을 거에요. 그런 다음, 이 두 개의 복사본을 합쳐서 새로운 객체를 만듭니다. 이렇게 만들어진 새로운 객체은 기존 객체의 속성들과 `data` 객체의 속성들이 합쳐져 있어요. 마지막으로, 이 새로운 객체를 `this.boards[index]`에 할당함으로써 기존 배열을 업데이트합니다. 이렇게 하면 기존 객체를 직접 변경하지 않고 새로운 값을 추가하거나 업데이트할 수 있어요. 간단하게 말하면, 이 코드는 배열에서 특정 객체를 찾아서 그 객체를 복사한 뒤, 새로운 값을 추가하거나 업데이트해서 배열을 업데이트하는 역할을 합니다. |
네, 스프레드 문법을 사용한 객체나 배열의 복사 및 합침은 JavaScript의 일반적인 기능 중 하나에요. 이를 통해 객체나 배열을 간편하게 복사하고 새로운 값을 추가하거나 업데이트할 수 있어요. 스프레드 문법을 사용한 객체의 복사 및 합침은 기본적으로 JavaScript 언어 자체의 문법입니다. 따라서 별도의 내장 함수가 아니라 JavaScript 엔진이 이를 지원하고 있습니다. 예를 들어, 아래와 같이 사용할 수 있어요.
이 코드에서 `...`은 스프레드 문법을 나타내며, 이를 통해 객체를 복사하거나 새로운 값을 추가 또는 업데이트할 수 있어요. 이러한 문법은 JavaScript의 ES6부터 도입되었습니다. |
실력 성장
빠르게 학습하는 개발자가 되는 방법 | 요즘IT (wishket.com)
좋은 엔지니어가 되려면 '경험' 쌓기가 중요합니다 | 요즘IT (wishket.com)
업무 관련
MariaDB & SQL Alchemy
ORM
SQLAlchemy 그것이 알고싶다 | Ulfrid_log
[Fastapi]SQLAlchemy 이용하여 DB와 연결하기 (velog.io)
sqlalchemay class (object) == db table
sqlalchemy class atttribute == db column
sqlalchemy class instance == db row
Relationship
[SQLAlchemy] 연관관계 설정 (tistory.com)
SQLAlchemy One to One 설정하기 (backref와 back_populates 차이) (tistory.com)
여태 내가 궁금한 사항이 인덱스 관련인줄 알았는데 알고 보니 릴레이션쉽이었다..
공식문서 링크 첨부 ㅜㅜㅜㅜ
Relationships API — SQLAlchemy 2.0 Documentation
Basic Relationship Patterns — SQLAlchemy 1.4 Documentation
gpt 설명
Q. sqlalchemy에서 relationship을 걸면 relationship이 걸린 테이블도 같이 조회돼? A. 네, 맞아요. SQLAlchemy에서 `relationship`을 사용하면 해당 관계가 정의된 모델 간에 객체 지향적인 방식으로 데이터를 로드할 수 있습니다. `relationship`을 통해 두 모델 간의 관계를 정의하면, 부모 모델을 쿼리할 때 자동으로 관련된 자식 모델도 함께 로드됩니다. 간단한 예제로 설명하자면, 예를 들어 `User`와 `Address`라는 두 모델이 있다고 가정해봅시다. `User` 모델에는 여러 개의 주소(`Address`)가 있을 수 있습니다. 이때 `relationship`을 사용하여 관계를 정의하면, `User`를 조회할 때 자동으로 해당 `User`의 주소들도 함께 조회됩니다.
위의 코드에서 `User` 모델과 `Address` 모델 간에 일대다 관계를 `relationship`을 사용하여 정의하고 있습니다. 이렇게 정의된 관계에서는 다음과 같이 `User`를 조회하면 연관된 주소들도 함께 로드됩니다.
이러한 기능은 관계형 데이터베이스의 조인과 유사한 동작을 수행하며, 객체 간의 관계를 편리하게 다룰 수 있도록 도와줍니다. |
Q. user 클래스에 id, name처럼 addresses라는 컬럼이 생기고, 그 컬럼에 Adderess relationship을 걸어줬으니 Address 클래스(테이블)의 모든 컬럼 값이 다 나온다는 거야? A. 네, 맞아요. `relationship`을 사용할 때, 해당 관계를 정의한 클래스(`User` 클래스의 `addresses` 속성)는 연관된 모델(`Address` 클래스)의 모든 열을 가지게 됩니다. 이는 SQLAlchemy에서의 일반적인 동작입니다. 예를 들어, 위에서 `User` 클래스에 `addresses`라는 `relationship`이 정의되었고, `Address` 클래스와의 관계가 정의되었습니다. 이 관계가 일대다 관계라면, `addresses` 속성은 해당 `User` 객체에 연결된 모든 주소를 나타내게 됩니다. 따라서 `addresses` 속성을 조회하면 해당 `User`에 대한 모든 주소 객체가 반환됩니다.
이때, `addresses` 속성에는 `Address` 클래스의 모든 컬럼 값이 담긴 주소 객체들이 포함되어 있습니다. 하지만 이 객체들이 로드되는 시점은 실제로 `addresses` 속성을 사용할 때이며, 필요한 경우에만 로드됩니다. 이를 "지연 로딩"이라고 부르며, 성능 상의 이점을 가져올 수 있습니다. |
요거에 대해서 좀 더 공부하고 정리해서 글 따로 써야겠다.
python 파이썬 - SQLalchemy에서 backref 및 back_populate의 개념? - 스택 오버플로 (stackoverflow.com)
여기 글을 읽다보니, 22년 7월부터 backref는 레거시로 간주되며 back_populates가 선호된다고 한다. 아마 어딘가 공식문서에 나와있는 거겠지? 근데 관계성 설명은 아직도 이해가 잘 안 간다.. 좀 공부해본 다음 직접 돌려봐야 하려나?
Timezone
MySQL & MariaDB 타임존 변경 (CONVERT_TZ 함수 이용) (tistory.com)
pytz – 세계 시간대 정의를 위한 Python 라이브러리 | edykim
Group by Alias 사용
Group By에 함수로 가공된 Alias를 사용해도 된다. : 네이버 블로그 (naver.com)
페이지네이션 (오프셋 기반 vs 커서 기반)
커서 기반 페이지네이션 (Cursor-based Pagination) 구현하기 (velog.io)
Cursor based Pagination(커서 기반 페이지네이션)이란? - Querydsl로 무한스크롤 구현하기 (velog.io)
인덱스
SQL 인덱스(INDEX) 뜻과 원리 이해하기(오라클, MS-SQL) : 네이버 블로그 (naver.com)
[MYSQL] 📚 인덱스(index) 핵심 설계 & 사용 문법 💯 총정리 (tistory.com)
데이터베이스 초보자를 위한 MS SQL INDEX (인덱스)사용법 : 네이버 블로그 (naver.com)
[DB] 인덱스(Index) 사용 예시 (생성, 조회, 삭제, 리빌드) (tistory.com)
Python
타입 명시
age: Union[int, None] = None
# ==
age: int | None = None
# ==
age: Optional[int] = None
셋 다 같은 사용법
파이썬에서 타입 힌트는 말 그대로 변수 타입에 대한 힌트일 뿐, 다른 타입을 사용한다고 해서 문제가 발생하지 않는다. (TypeScriptt에서는 이렇게 작성하면 타입체커가 열일을 시작하지.)
문법
날짜 시간 관련 포맷
[python] datetime 모듈 strftime 메소드, 포맷(format) 코드 정리 by bskyvision.com
*args, **kwargs, dict()
이건.. JS의 스프레드 문법 같은 거 없을까? 생각하다가 오? 하고 찾아서 사용법 알아보는 중..
*args 와 **kwargs 사용하기 - 슬기로운 파이썬 트릭 中 (tistory.com)
글 이해한 내용 정리
args kwargs
: argument unpacking
: 함수 정의에 주로 사용됨
args
: 이름이 없는 인자로 구성된 tuple
kwargs
: 이름이 주어진 인자로 구성된 dict
함수 인자 풀기
*, ** 연산자를 잘 사용하면
연속된 데이터(*)와
딕셔너리(**)에서
함수 인자를 풀어내는 기능을 쉽게 할 수 있다
def print_vector(x, y, z):
print(f"<{x}, {y}, {z}>")
tuple_vec = (1, 2, 3)
list_vec = [1, 2, 3]
이렇게 튜플이나 리스트로 만들어진 값이 담긴 변수를 *을 이용하면 여러 개의 인자를 요구하는 함수에 한 번에 넘겨줄 수 있다
dictonary 같은 경우 **로 풀면 값만 알아서 따서 프린트된..다?
dict_vec = {"x": 1, "y": 5, "z": 10}
print_vector(**dict_vec)
출력: <1, 5, 10>
<<내가 이해한 바를 정리하자면>>
함수에 받을 인자 개수를 확실하게 알 수 없을 때,
함수에 여러 개의 인자를 편하게 넘기고 싶을 때 사용하면 좋은 것 같다.
함수에서 사용하는 꿀팁으로 알려주신 ** 방법은 내가 파이썬 공부를 조금 더 해야할 것 같다. 이해는 되는데 다르게 활용해보라고 하면 아직 정확한 이해가 된 것이 아니라서 감으로 대충 때려맞출 정도..? 이기 때문에 나중에 내 코드 다시 봤을 때 '음..? 뭐였..더라? 아 실행해봐야지.. 아 이런 거였구나.. 음.. 다시 문서를 봐볼까?'할 것 같다.
for문과 if문을 한 줄에! - 리스트 컴프리헨션
1) 리스트 컴프리헨션 - 제대로 파이썬 (wikidocs.net)
.dict(), .ittems(), setattr()
sqlalchemy랑 fastaapi pydantic schema 관련으로 궁금한 사항이라서 찾아봄
[ Python 3 ] 딕셔너리(dictionary) 생성 ({}, dict ()) (tistory.com)
딕셔너리 타입?
- 키(Key; immutable)와 값(value: mutable)으로 매핑되어 있는 순서가 없는 집합
- json 형식과 같
.dict()
- dict constructor로 파이썬 구현 과정에서 많이 사용됨
파이썬 setattr 함수를 사용해 봅시다. (tistory.com)
Python Schema library 정리 (tistory.com)
schema
- JSON/YAML(또는 다른것들)에서 python 데이터 타입으로 변환된 config file, forms, 외부 서비스 또는 command-line 파싱에서 얻은 것과 같은 python 데이터 구조를 검증하기 위한 라이브러리
Fast API, Schema 예시 설정 및 데이터 타입 (velog.io)
swagger 작성할 때 fastapi에서도 작성 예시를 직접 들어줄 수 있나보다
FastAPI
Uvicorn
FastAPI 애플리케이션에 uvicorn 직접 가져와서 실행하기 - 디버깅 - FastAPI (tiangolo.com)
위 방법을 이용하면 uvicorn 명령어가 아닌 python 명령어로 앱 실행 가능해짐
[fastapi] uvicorn, fastapi 비동기 메커니즘 이해 : 네이버 블로그 (naver.com)
여기를 통해서 알게 된 건데, gunicorn은 uvicorn 프로세스를 관리하는 프로세스로 nodejs에서 pm2와 유사한 개념임.
단, nodejs가 쓰레드 기반 구현이라면 asgi server, asgi framework는 프로세스 기반으로 구현.
상세하게 읽어볼 필요 있어 보임.
__main__ --- 최상위 코드 환경 — Python 3.12.0 documentation
__main__에 대한 궁금증으로 파이썬 문서 가져옴..!
Pydantic
pydantic을 사용하여, 안정성 높이기 — re-code-cord (tistory.com)
앞서 파이썬 타입 명시에서 설명했듯 파이썬은 변수 타입이 이렇다 힌트만 줄 뿐, 강제하지 않는다. pydantic은 런타입에서 타입 힌트를 강제하고 유효하지 않으면 error를 발생시킨다.
pydantic은 정확하게 따지자면 parsing 라이브러리.
Optional 특성도 여기서 알게 됐다.
fastapi 공식문서를 보다 보면 스키마에서 각 필드별로 타입 지정을 해줄 때 아래와 같이 해주고 있다.
# Python3.10~
description: str | None = None
# ~Python3.9
description: Union[str, None] = None
Optional을 이용하면 Optional[str] = None 이렇게 사용해줄 필요 없이 한 번만 기입하면 된다고 한다.
이렇게 편할 수가.. 글자 입력 조금이라도 덜할 수 있는 방식이었네.
이게 가능한 이유는, python에서 제공하는 자료형 뿐만 아니라 typing datetime 등 일반적인 자료형을 지원하며 이외에도 직접 만들어서 사용할 수도 있고 기존의 자료형을 제한해서 사용하는 것도 가능하다고 한다.
[Fastapi]SQLAlchemy 이용하여 DB와 연결하기 (velog.io)
sqlalchemy 쪽에서도 언급하고 있는 글인데, pydantic에 대한 설명이 있어서 여기에도 끌어왔다.
pydantic orm_mode : dictionary 자료형이 아니라도 읽을 수 있게 해줌
orm_mode가 아니라면, path operation으로부터 SQLAlchemy model을 반환했을 때 relationship data는 반환하지 않을 것
이러한 이유로 'select를 제외한 경우에 사용해야 하는구나!' -> 'relationship을 걸었다면 orm_mode를 걸어줘야 한다고?'로 이어지며 이해되지 않던 생각의 고리가 드디어 이해되면서 탄탄해졌다.
Body 중첩 모델
Body - Nested Models - FastAPI (tiangolo.com)
sqlalchemy에서 relationship으로 가져온 내용을 스키마에 담아 보낼 때 이 모델을 사용하는 걸 봤다. 설명이 여기 있었군.
HTTP Exception 일괄 처리
logger에 기록되도록 except처리를 할 때 일반 에러를 잡는 것 말고 http exception일 때 따로 상태코드별로 기록할 수 있도록 하는 방법을 알고 싶어 gpt와 열심히 대화를 나눠보았다.
A. 404 에러를 처리하는 예외를 던지기 위해서는 해당 상황에 대한 조건문이나 검사를 통해 HTTPException을 발생시키면 됩니다. 아래는 간단한 예제입니다:
이렇게 하면 특정 조건이 만족되었을 때 404 에러를 발생시키고, 그 외의 예외에 대해서는 500 에러를 발생시키도록 할 수 있어요. Q. 아 그렇게 하면 404 이외의 에러가 발생하더라도 모두 except HTTPException as http_exception으로 빠져서 로거에 기록하는 로직은 간단화해줄 수 있겠네? A. 맞아요. `HTTPException`은 FastAPI에서 예외 처리를 위해 특별히 설계된 예외 클래스이기 때문에, HTTP 상태 코드와 상세 메시지를 제어하기 용이합니다. 따라서 특정 상황에서 404 에러를 발생시켜 처리하고, 그 외의 예외에 대해서는 기본적으로 500 에러를 발생시켜 로깅하면 코드가 간결해지고 유지보수가 편리해집니다. |
Ubuntu 관련???
screen
Linux/기본명령어/screen - 인코덤, 생물정보 전문위키 (incodom.kr)
[Linux] screen 명령어 :: 토마스의 기술 정리함 (tistory.com)
백그라운드로 돌리면서 포어그라운드로 가져왔다가 다시 돌려놓는 시스템이라니... 너무 신기하잖아?!
이렇게 또 배운다.. 재미있다
스크린을 만들고 로그파일 생성도 가능한가 보다. 오호..
아래는 screen에 대한 이해를 위해 gpt와 수다수다한 내용
네, Docker 컨테이너 내에서 `screen`을 사용하면 그것은 컨테이너 내부에서의 터미널 세션을 의미할 거야. 간단한 비유로 설명하자면, Docker 컨테이너는 격리된 환경에서 실행되는 가상화된 프로세스이며, 이 컨테이너 내부에서의 터미널 세션은 그 안에서 동작하는 프로세스를 모니터링하거나 명령어를 실행할 수 있는 창문 같은 역할을 하는 거야. 예를 들어, 당신이 백엔드 서버를 Docker 컨테이너 내에서 실행하고 있다고 가정해봐. 그리고 그 컨테이너 내부에서 `screen`을 사용하여 백엔드 프로세스를 실행하고 있다면, 이 `screen` 세션은 컨테이너 내부에 있는 것이야. 그래서 외부에서 `screen` 명령어를 사용하면 컨테이너 내부의 터미널로 연결되는 것처럼 보일 거야. 이 비유로 생각해보면, Docker 컨테이너는 하나의 방(가상 환경)이고, 그 방 안에서 `screen`은 그 방의 창문이라고 생각할 수 있어. 창문을 통해 방 안의 일이나 프로세스를 확인하고 제어할 수 있게 돼. |
Q. 그러면 질문, docker 컨테이너 bash로 접근하는 것과 screen으로 접근하는 것의 차이가 뭐야? A. Docker 컨테이너에 접근하는 방법은 크게 두 가지가 있어: `bash`로 직접 접근하는 것과 `screen`과 같은 터미널 멀티플렉서를 사용하는 것. 1. **Bash로 직접 접근:** - `docker exec -it <container_id> /bin/bash`와 같은 명령을 사용하면 컨테이너 내부의 Bash 셸에 직접 접근할 수 있어. 이는 컨테이너 내에서 명령을 실행하거나 파일을 확인하는 데 유용해. 2. **Screen 또는 다른 터미널 멀티플렉서를 사용:** - `screen` 또는 `tmux`와 같은 터미널 멀티플렉서를 사용하면 컨테이너 내에서 여러 작업을 동시에 실행하고 관리할 수 있어. 예를 들어, 백그라운드에서 돌아가는 프로세스를 유지하거나 여러 터미널 세션 간에 이동할 수 있어. 간단하게 말하자면, `bash`로 직접 접근하는 것은 컨테이너 내에서 명령을 실행하고 작업을 수행하는 데 사용되는 반면, `screen`과 같은 터미널 멀티플렉서는 여러 터미널 세션을 관리하고 백그라운드에서 실행 중인 작업을 유지하는 데 유용하게 사용돼. |
Q. bash로 접근하는 것은 일반적으로 ubuntu 서버를 ssh로 여러 명이 붙어서 작업하는 것처럼 할 수 없고 한 명만 접근이 가능한 거야? ssh로 여러 명이 붙어서 작업할 수 있도록 돕는 게 screen이라고 이해하면 되려나? 그러면서 nohup처럼 백그라운드로 돌리면서 언제든지 포어그라운드로 올렸다 내렸다도 할 수 있는 거구?? A. 맞아, 네 말이 맞아! `bash`로 직접 접근하는 것은 주로 한 명의 사용자만 접근이 가능한 반면, `screen`이나 `tmux`와 같은 터미널 멀티플렉서를 사용하면 여러 사용자가 동시에 접근하여 작업할 수 있어. `screen`을 예로 들면, 이는 세션을 생성하여 각 세션에서 독립적으로 작업할 수 있게 해주어 여러 사용자가 동시에 작업할 수 있도록 돕는다. 이렇게 하면 SSH로 여러 명이 접속해서 각자의 세션에서 작업할 수 있게 되어 효율적인 협업이 가능해진다. 또한, `nohup`과 비슷하게 백그라운드에서 프로세스를 실행하면서, `screen`을 통해 세션을 유지하고 필요할 때 포그라운드로 올려서 상호작용할 수도 있어. 이는 장기적으로 실행되는 작업이나 서버 프로세스를 관리하는 데에 유용하다. 요약하자면, `screen`을 사용하면 여러 사용자가 동시에 작업할 수 있고, 백그라운드에서 실행 중인 작업을 관리하면서 언제든지 포그라운드로 전환하여 상호작용할 수 있다. |
'내 지식 정리 > 날것 그 자체' 카테고리의 다른 글
2023.12. 개발 궁금증 링크 일기 (0) | 2023.12.04 |
---|---|
[Git] 마스터하기 (0) | 2023.11.18 |
2023.10. 개발 궁금증 링크 일기 (0) | 2023.10.11 |
[AWS] Elastic Beanstalk으로 Node.js 앱 배포 트러블 슈팅 좌충우돌기 (0) | 2023.09.09 |
2023.09. 개발 궁금증 링크 일기 (0) | 2023.09.01 |