- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동 - book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서) - 빈 폴더 제거 (journey/assets/*)
103 lines
3.8 KiB
Markdown
103 lines
3.8 KiB
Markdown
# 자동 코드생성 및 수정
|
|
|
|
1. 개요
|
|
2. 방법
|
|
3. TIP
|
|
|
|
## 1. 개요
|
|
|
|
해당 방법은 `sqlcodegen`을 통해 DB의 데이터를 `ORM`방식으로 전환하는 방법이다.</br>
|
|
이번에는 `PostgreSQL`을 기준으로 작성하였다.
|
|
|
|
## 2. 방법
|
|
|
|
먼저 다른 lib와 충돌을 위해 별도의 venv를 생성 후 아래의 lib를 설치한다.
|
|
```bash
|
|
pip install psycopg2-binary sqlacodegen SQLAlchemy
|
|
```
|
|
|
|
해당 명령어를 입력 후, 아래의 명령어를 통해 ORM를 자동생성한다.
|
|
```bash
|
|
sqlacodegen postgresql://{{id}}:{{passwd}}@{{DB URL or IP}}:{{port}}/{{DB schema}} > {{file명 i.e.) models.py}}
|
|
```
|
|
|
|
해당 명령어를 통해 아래와 같은 코드가 작성된다.
|
|
|
|
```python
|
|
from typing import Optional
|
|
import datetime
|
|
import uuid
|
|
|
|
from sqlalchemy import (ARRAY, Boolean, DateTime, Double, Enum, ForeignKeyConstraint, Index, Integer, JSON, PrimaryKeyConstraint, String, Time, UniqueConstraint, Uuid, text, Sequence, func)
|
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
|
|
|
|
class Base(DeclarativeBase):
|
|
pass
|
|
|
|
|
|
class Company(Base):
|
|
__tablename__ = 'company'
|
|
__table_args__ = (
|
|
PrimaryKeyConstraint('id', name='company_pk'),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
|
|
name: Mapped[str] = mapped_column(String(255), nullable=False)
|
|
url: Mapped[Optional[str]] = mapped_column(String(255))
|
|
created_at: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime(True), server_default=func.now())
|
|
updated_at: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime(True), server_default=func.now(), onupdate=func.now())
|
|
|
|
team: Mapped[list['Team']] = relationship('Team', back_populates='company')
|
|
|
|
|
|
class Product(Base):
|
|
__tablename__ = 'product'
|
|
__table_args__ = (
|
|
PrimaryKeyConstraint('id', name='product_pk'),
|
|
)
|
|
|
|
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
|
|
name: Mapped[str] = mapped_column(String(32), nullable=False)
|
|
app_id: Mapped[Optional[str]] = mapped_column(String(16))
|
|
scope: Mapped[Optional[dict]] = mapped_column(JSON)
|
|
description: Mapped[Optional[str]] = mapped_column(String(256))
|
|
created_at: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime(True), server_default=func.now())
|
|
updated_at: Mapped[Optional[datetime.datetime]] = mapped_column(DateTime(True), server_default=func.now(), onupdate=func.now())
|
|
|
|
robeing: Mapped[list['Robeing']] = relationship('Robeing', back_populates='product')
|
|
|
|
...
|
|
```
|
|
|
|
## 3. TIP
|
|
|
|
해당 항목은 자동으로 생성될 시, 몇가지 수정점이 있으므로 아래와 같은 주의사항을 작성하였다.
|
|
|
|
- `SEQUENCE`는 자동으로 작성되지 않는다.</br>
|
|
그러므로 아래와 같은 방식으로 Colume에 추가한다.
|
|
|
|
- ~에서
|
|
```python
|
|
....
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True)
|
|
....
|
|
```
|
|
|
|
- ~으로
|
|
```python
|
|
....
|
|
id: Mapped[int] = mapped_column(Integer, Sequence('conversation_log_id_seq'), primary_key=True)
|
|
....
|
|
```
|
|
|
|
- DB에서 Default값을 작성시에는 상황에 맞게 수정한다.
|
|
- case 1. 서버에서 기본값이 들어가야하는 경우
|
|
해당경우는 code에서 기본값을 작성하여 DB에 insert 한다.</br>
|
|
i.e.) datezone의 경우: `sqlalchemy`의 func.now()</br>
|
|
uuid의 경우: uuid.uuid4</br>
|
|
※ DB의 호환성을 고려하여 만약 오류가 발생시 적절한 방법을 찾아서 코드로 구현한다.
|
|
- case 2. DB에서 처리해도 되는 경우와 DB의 호환성을 고려하는 경우
|
|
해당경우는 sqlcodegen에서 자동생성된 코드를 그대로 사용한다.</br>
|
|
i.e.) jwt의 경우: `server_default=text("'Bearer'::character varying")` 그대로 사용한다.</br>
|