SQLAlchemy ORM에 테이블을 지연 반영
9849 단어 discusswebdevpythonprogramming
Flask
또는 FastAPI
와 같은 백엔드 프레임워크에서 작업할 때 일반적으로 이 ORM을 접하게 됩니다.SQLAlchemy
를 사용할 수 있는 두 가지 접근 방식이 있습니다.declarative_base
객체를 사용하여 스키마, 테이블을 수동으로 생성하고 마이그레이션합니다. metadata
를 사용하여 데이터베이스의 기존 개체를 반영합니다. 이후 접근 방식의 문제는 작업할 테이블이 많을 때 모든 테이블에 대한 초기 반영에 많은 시간이 걸리고 응용 프로그램 부팅 시간이 증가한다는 것입니다. 애플리케이션 성능 저하 없이 기존 테이블을 반영해야 하는 상황을 해결하기 위한 접근 방식을 생각해 냈습니다.
아이디어는 한 번에 모든 것을 로드하는 대신 요구 사항에 따라 테이블과 뷰를 느리게 반영하는 것입니다. 한 번에 모든 테이블을 요구하지는 않습니다. 그렇죠?
API는 테이블의 하위 집합에서 쿼리하거나 CRUD 작업을 수행하기 때문에 다른 테이블 로드를 건너뛸 수 있는 공간이 있지만 이미 반영된 테이블을 지속적으로 유지할 수도 있습니다.
요구 사항에 대한 테이블을 한 번만 반영하고 앞으로 동일한 개체를 사용할 수 있도록 유지하는 래퍼
lazy
를 만들었습니다.class LazyDBProp(object):
"""This descriptor returns sqlalchemy
Table class which can be used to query
table from the schema
"""
def __init__(self) -> None:
self._table = None
self._name = None
def __set_name__(self, _, name):
self._name = name
def __set__(self, instance, value):
if isinstance(value, (CustomTable, Table)):
self._table = value
def __get__(self, instance, _):
if self._table is None:
self._table = CustomTable(
self._name, instance.metadata, autoload=True)
return self._table
이 클래스는 내부적으로
descriptors
를 사용하여 table
또는 view
개체를 유지합니다. 또한 이러한 디스크립터 기반 테이블 개체를 보유할 동적 클래스를 생성하는 래퍼를 만들었습니다.def get_lazy_class(engine: Engine) -> object:
"""
Function to create Lazy class for pulling table object
using SQLalchemy metadata
"""
def __init__(self, engine: Engine):
self.metadata = MetaData(engine)
self.engine = engine
def __getattr__(self, attr):
if attr not in self.__dict__:
obj = self.__patch(attr)
return obj.__get__(self, type(self))
def __patch(self, attribute):
obj = LazyDBProp()
obj.__set_name__(self, attribute)
setattr(type(self), attribute, obj)
return obj
# naming classes uniquely for different schema's
# to avoid cross referencing
LazyClass = type(f"LazyClass_{engine.url.database}", (), {})
LazyClass.__init__ = __init__
LazyClass.__getattr__ = __getattr__
LazyClass.__patch = __patch
return LazyClass(engine)
위 클래스는 아래와 같이 간단하게 사용할 수 있습니다.
from lazy_alchemy import get_lazy_class
from sqlalchemy import create_engine
db_engine = create_engine(DB_CONNECT_STRING)
lazy_db = get_lazy_class(db_engine)
db_model = lazy_db.my_db_table_foo
query = session.query(db_model).filter(db_model.foo == "bar").all()
일단 반영되면 이러한 개체를 반복적으로 참조할 수 있습니다. 필요한 객체만 반영하면 최소한의 오버헤드로 애플리케이션 성능이 향상됩니다.
이로 인해 응용 프로그램 부팅 시간이 1분 이상에서 몇 초로 단축되었습니다 :).
프로젝트에서 위의 내용을 구현하려면 간단히 내 pypi 패키지Lazy Alchemy를 사용할 수 있습니다.
이 접근법에 대한 귀하의 견해와 대안을 듣고 싶습니다.
이 글을 읽어 주셔서 감사합니다. 유용한 정보를 찾으셨기를 바랍니다.
Reference
이 문제에 관하여(SQLAlchemy ORM에 테이블을 지연 반영), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/satyamsoni2211/lazy-reflecting-tables-to-sqlalchemy-orm-ng5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)