[PYTHON] SQLAlchemy ORM에서 열 데이터 형식을 어떻게 확인할 수 있습니까?
PYTHONSQLAlchemy ORM에서 열 데이터 형식을 어떻게 확인할 수 있습니까?
SQLAlchemy ORM을 사용하여 값이 해당 열에 적합한 유형인지 확인하고자합니다.
예를 들어 정수 열이 있다고 가정합니다. 유효한 정수가 아닌 값 "hello"를 삽입하려고합니다. SQLAlchemy를 사용하면이 작업을 수행 할 수 있습니다. 나중에 만 session.commit ()을 실행하면 예외가 발생합니다. sqlalchemy.exc.DataError : (DataError) 잘못된 입력 구문 integer : "hello"....
레코드 일괄 처리를 추가하고 있으며 성능상의 이유로 모든 추가 (...) 후 커밋하고 싶지 않습니다.
어떻게하면됩니까?
해결법
-
==============================
1.SQLAlchemy는 DBAPI / 데이터베이스에서 값의 유효성 검사 및 강제 변환의 가장 효율적이고 효율적인 소스로 사용할 수 있으므로이 기능을 빌드하지 않습니다.
SQLAlchemy는 DBAPI / 데이터베이스에서 값의 유효성 검사 및 강제 변환의 가장 효율적이고 효율적인 소스로 사용할 수 있으므로이 기능을 빌드하지 않습니다.
자신의 유효성 검사를 수행하려면 대개 TypeDecorator 또는 ORM 수준 유효성 검사가 사용됩니다. TypeDecorator는 코어에서 작동하고 꽤 투명 할 수 있다는 이점이 있지만 SQL이 실제로 출력 될 때만 발생합니다.
유효성 검사와 강제 변환을 더 빨리 수행하기 위해 이것은 ORM 레벨에 있습니다.
유효성 검사는 @validates를 통해 ORM 계층에서 ad-hoc 일 수 있습니다.
http://docs.sqlalchemy.org/en/latest/orm/mapped_attributes.html#simple-validators
@validates가 사용하는 이벤트 시스템도 직접 사용할 수 있습니다. 선택한 유효성 검사기를 매핑되는 유형에 연결하는 일반화 된 솔루션을 작성할 수 있습니다.
from sqlalchemy import Column, Integer, String, DateTime from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import event import datetime Base= declarative_base() def validate_int(value): if isinstance(value, basestring): value = int(value) else: assert isinstance(value, int) return value def validate_string(value): assert isinstance(value, basestring) return value def validate_datetime(value): assert isinstance(value, datetime.datetime) return value validators = { Integer:validate_int, String:validate_string, DateTime:validate_datetime, } # this event is called whenever an attribute # on a class is instrumented @event.listens_for(Base, 'attribute_instrument') def configure_listener(class_, key, inst): if not hasattr(inst.property, 'columns'): return # this event is called whenever a "set" # occurs on that instrumented attribute @event.listens_for(inst, "set", retval=True) def set_(instance, value, oldvalue, initiator): validator = validators.get(inst.property.columns[0].type.__class__) if validator: return validator(value) else: return value class MyObject(Base): __tablename__ = 'mytable' id = Column(Integer, primary_key=True) svalue = Column(String) ivalue = Column(Integer) dvalue = Column(DateTime) m = MyObject() m.svalue = "ASdf" m.ivalue = "45" m.dvalue = "not a date"
TypeDecorator를 사용하여 유형 수준에서 유효성 검사 및 강제 변환을 만들 수도 있습니다. 단, SQL이 방출 될 때만 가능합니다 (예 : utf-8 문자열을 유니 코드로 강제 변환하는이 예제).
http://docs.sqlalchemy.org/en/latest/core/custom_types.html#coercing-encoded-strings-to-unicode
-
==============================
2.@zzzeek의 대답을 향상시키면서 다음 해결책을 제안합니다.
@zzzeek의 대답을 향상시키면서 다음 해결책을 제안합니다.
from sqlalchemy import String from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.event import listen_for Base = declarative_base() @listens_for(Base, 'attribute_instrument') def configure_listener(table_cls, attr, col_inst): if not hasattr(col_inst.property, 'columns'): return validator = getattr(col_inst.property.columns[0].type, 'validator', None) if validator: # Only decorate columns, that need to be decorated @listens_for(col_inst, "set", retval=True) def set_(instance, value, oldvalue, initiator): return validator(value)
그렇게하면 다음과 같은 일을 할 수 있습니다.
class Name(String): def validator(self, name): if isinstance(name, str): return name.upper() raise TypeError("name must be a string")
여기에는 두 가지 이점이 있습니다. 첫째, 실제로 데이터 필드 객체에 연결된 유효성 검사기가있을 때 이벤트가 트리거됩니다. 유효성 검사를 위해 정의 된 기능이없는 객체의 설정 이벤트에 귀중한 CPU 사이클을 낭비하지 않습니다. 둘째, 자신의 필드 유형을 정의하고 거기에 유효성 검사기 메소드를 추가 할 수 있으므로 Integer 등으로 저장하려는 모든 항목이 새 필드 유형에서 파생 된 것과 동일한 검사를 거치지는 않습니다.
from https://stackoverflow.com/questions/8980735/how-can-i-verify-column-data-types-in-the-sqlalchemy-orm by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] Django : 사후 저장 신호를 사용하여 저장 대 커스터마이즈 할 때 (0) | 2018.11.22 |
---|---|
[PYTHON] csv의 컬럼에 파이썬리스트 작성하기 (0) | 2018.11.22 |
[PYTHON] numpy에 대한 메모리 프로파일 러 (0) | 2018.11.22 |
[PYTHON] 코드 완성을 통한 Python / django의 숭고한 텍스트 2 및 3 설정 (0) | 2018.11.22 |
[PYTHON] 괄호 안에없는 쉼표로 분리하는 방법은 무엇입니까? (0) | 2018.11.22 |