SQLAlchemy에서 Table Join을 복잡하게 하는 경우가 많아, 가급적 쉬운 방법을 찾아보았다.
전체소스 코드 : https://github.com/armyost/hexagonalSample/tree/main
GitHub - armyost/hexagonalSample: This is python Sample with Hexagonal Architecture
This is python Sample with Hexagonal Architecture. Contribute to armyost/hexagonalSample development by creating an account on GitHub.
github.com
1-1) src/app/domain/models/user.py 에 Class 모델 정의
class User:
def __init__(self, userId, description, userName, deptId):
self.userId = userId
self.description = description
self.userName = userName
self.deptId = deptId
def __repr__(self):
return f'<User {self.userId}>'
def as_dict(self):
return {
'userId': self.userId,
'description': self.description,
'userName': self.userName,
'deptId': self.deptId
}
1-2) src/app/domain/models/department.py 에 Class 모델 정의
class Department:
def __init__(self, deptId, description, deptName):
self.deptId = deptId
self.description = description
self.deptName = deptName
def __repr__(self):
return f'<Department {self.deptId}>'
def as_dict(self):
return {
'deptId': self.deptId,
'description': self.description,
'deptName': self.deptName
}
2-1) src/app/domain/repositories/user_repository_interface.py 에 다음과 같이 인터페이스 정의
from abc import (
ABCMeta,
abstractmethod
)
class UserRepositoryInterface:
__metaclass__ = ABCMeta
@abstractmethod
def insert(self, user):
pass
@abstractmethod
def selectWithDeptInfo(self, userId):
pass
2-2) src/app/domain/repositories/department_repository_interface.py 에 다음과 같이 인터페이스 정의
from abc import (
ABCMeta,
abstractmethod
)
class DepartmentRepositoryInterface:
__metaclass__ = ABCMeta
@abstractmethod
def insert(self, department):
pass
3) src/app/infrastructure/database.py 에 다음과 같이 정의
users_table = Table(
'user', metadata,
Column('userId', Integer, primary_key=True),
Column('description', Text, nullable=True),
Column('userName', String(10), nullable=True),
Column('deptId', Integer, ForeignKey("department.deptId"), nullable=True)
)
departments_table = Table(
'department', metadata,
Column('deptId', Integer, primary_key=True),
Column('description', Text, nullable=True),
Column('deptName', String(10), nullable=True)
)
※ MetaData 형식의 테이블 매핑 정의서 만드는 링크
https://docs.sqlalchemy.org/en/20/core/metadata.html
Describing Databases with MetaData — SQLAlchemy 2.0 Documentation
Describing Databases with MetaData This section discusses the fundamental Table, Column and MetaData objects. A collection of metadata entities is stored in an object aptly named MetaData: from sqlalchemy import MetaData metadata_obj = MetaData() MetaData
docs.sqlalchemy.org
4-1) src/app/infrastructure/repositories/user_repository.py 에서 UserRepository 구현하고,
class UserRepository(BaseRepository, UserRepositoryInterface):
def insert(self, user):
with self.db_connection.begin():
self.db_connection.execute(
users_table.insert(),
user.as_dict()
)
def selectWithDeptInfo(self, userId):
with self.db_connection.begin():
stmt = select(users_table, departments_table).outerjoin(departments_table, users_table.c.deptId == departments_table.c.deptId).where(users_table.c.userId == userId)
row = self.db_connection.execute(stmt).fetchone()
return {
'userId' : row['userId'],
'userName' : row['userName'],
'deptName' : row['deptName']
} if row else None
4-2) src/app/infrastructure/repositories/department_repository.py 에서 DepartmentRepository 구현한다.
class DepartmentRepository(BaseRepository, DepartmentRepositoryInterface):
def insert(self, department):
with self.db_connection.begin():
self.db_connection.execute(
departments_table.insert(),
department.as_dict()
)
※ SQLAlchemy의 Query정의 문서 : https://docs.sqlalchemy.org/en/20/orm/queryguide/select.html
'Programming > Python' 카테고리의 다른 글
Nori Tokenizer를 활용한 검색서버 개발 (1) | 2023.10.23 |
---|---|
ElasticSearch 406에러 (0) | 2023.10.19 |
Python 에서 pip install할때 발생하는 오류들 (0) | 2023.03.21 |
(Python) Pytest로 Unit-test 구현하기 (0) | 2021.05.31 |
(Python) 트위터 메인프레임만들기 (0) | 2021.05.04 |