Simple 하게 Python 에서 orm 사용하기
python 에서 orm을 사용할일이 생겨서 orm을 찾던중 sqlAlchemy 는 너무 문서가 잘 읽히지 않고 옜날 느낌이라서..
https://docs.sqlalchemy.org/en/14/
좀더 문서화가 잘 되어있고 github 에서도 star 가 많은것을 찾다가 peewee를 찾게되었습니다.
http://docs.peewee-orm.com/en/latest/
문서화도 잘되어 있고 Mysql, postgres, sqlite3 ..등 많은 sql driver 를 지원해줘서 사용하게 되었습니다.
Connection
domain/base.py
from peewee import PostgresqlDatabase, Model
from playhouse.reflection import generate_models
import logging
from config import conf
logger = logging.getLogger("peewee")
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
db_url = conf.DATABASE["URL"]
user_id = conf.DATABASE["USER_ID"]
user_password = conf.DATABASE["USER_PASSWORD"]
psql_db = PostgresqlDatabase(
"postgres", user=user_id, password=user_password, host=db_url, port=5432
)
psql_db.connect()
class BaseModel(Model):
"""A base model that will use our Postgresql database"""
class Meta:
database = psql_db
logger 를 추가하여 SQL 쿼리문을 디버깅 할수 있게 추가하였습니다.
psql host, user id, password 를 config 파일에서 불러와 Postgresql DB를 생성하고 connection합니다.
connection 이 성공하면 True를 반환합니다.
BaseModel 앞으로 만들 각종 Table이 상속하게 될 부모 Class입니다.
Table Class
domain/shop_device.py
from domain.base import BaseModel
from peewee import IntegerField, CharField, DateTimeField
class ShopDevice(BaseModel):
class Meta:
db_table = "shop_device"
# primary_key == auto increment
id = IntegerField(primary_key=True, db_column="shop_device_id")
shop_id = IntegerField()
panel_id = CharField()
panel_maker = CharField()
panel_size = IntegerField()
screen_ratio = CharField()
settop_id = CharField()
shop_display_id = IntegerField()
status = IntegerField()
last_check_at = DateTimeField()
sort_no = IntegerField()
whole_display_path = CharField()
thumbnail_path = CharField()
created_at = DateTimeField()
updated_at = DateTimeField()
class명이 카멜 케이스 인데 table 명은 스네이크 일때 class Meta 에 db_table에 직접 테이블명을 명시 할수 있습니다.
peewee는 기본적으로 id 값이 primary_key = True 라면 auto increment 도 True 입니다.
Create
>>> user = User(username='Charlie')
>>> user.save() # save() returns the number of rows modified.
1
>>> user.id
1
>>> huey = User()
>>> huey.username = 'Huey'
>>> huey.save()
1
>>> huey.id
2
>>> tweet = Tweet.create(user=huey, message='Hello!')
>>> tweet = Tweet.create(user=2, message='Hello again!')
>>> User.insert(username='Mickey').execute()
3
원하는 방식중에 선택하셔서 사용하시면 될거같습니다.
Update
>>> for stat in Stat.select().where(Stat.url == request.url):
... stat.counter += 1
... stat.save()
이것은 peewee에서 지양하는 방식입니다. 여러 프로세스가 동시에 카운터를 업데이트하는 경우 경쟁 조건에 취약하기 때문입니다.
>>> query = Stat.update(counter=Stat.counter + 1).where(Stat.url == request.url)
>>> query.execute()
전자 대신 후자의 방식으로 업데이트 하는것을 권장드립니다.
Get
>>> User.get(User.id == 1)
<__main__.User object at 0x25294d0>
>>> User.get_by_id(1) # Same as above.
<__main__.User object at 0x252df10>
>>> User[1] # Also same as above.
<__main__.User object at 0x252dd10>
>>> User.get(User.id == 1).username
u'Charlie'
>>> User.get(User.username == 'Charlie')
<__main__.User object at 0x2529410>
>>> User.get(User.username == 'nobody')
UserDoesNotExist: instance matching query does not exist:
SQL: SELECT t1."id", t1."username" FROM "user" AS t1 WHERE t1."username" = ?
PARAMS: ['nobody']
- Model.get()
- Model.get_by_id()
- Model.get_or_none()- 일치하는 행이 없으면 를 반환 None합니다.
- Model.select()
- SelectBase.get()
- SelectBase.first()- 결과 집합의 첫 번째 레코드를 반환하거나 None.
Select
>>> for user in User.select():
... print(user.username)
...
Charlie
Huey
Peewee
다른 문법들이 더 궁금하신분들은 위에 있는 공식문서 링크를 통해 확인하시면 될것 같습니다!
'Python' 카테고리의 다른 글
튜플 정렬하기 - operator itemgetter 메서드 (0) | 2020.10.10 |
---|---|
문자열 정렬하기 - ljust, center, rjust (0) | 2020.09.30 |
python 진법 변환 (0) | 2020.09.30 |
몫과 나머지 - divmod (0) | 2020.09.30 |
댓글
이 글 공유하기
다른 글
-
튜플 정렬하기 - operator itemgetter 메서드
튜플 정렬하기 - operator itemgetter 메서드
2020.10.10 -
문자열 정렬하기 - ljust, center, rjust
문자열 정렬하기 - ljust, center, rjust
2020.09.30 -
python 진법 변환
python 진법 변환
2020.09.30 -
몫과 나머지 - divmod
몫과 나머지 - divmod
2020.09.30