복붙노트

[PYTHON] SQLAlchemy ORM에서 열 데이터 형식을 어떻게 확인할 수 있습니까?

PYTHON

SQLAlchemy ORM에서 열 데이터 형식을 어떻게 확인할 수 있습니까?

SQLAlchemy ORM을 사용하여 값이 해당 열에 적합한 유형인지 확인하고자합니다.

예를 들어 정수 열이 있다고 가정합니다. 유효한 정수가 아닌 값 "hello"를 삽입하려고합니다. SQLAlchemy를 사용하면이 작업을 수행 할 수 있습니다. 나중에 만 session.commit ()을 실행하면 예외가 발생합니다. sqlalchemy.exc.DataError : (DataError) 잘못된 입력 구문 integer : "hello"....

레코드 일괄 처리를 추가하고 있으며 성능상의 이유로 모든 추가 (...) 후 커밋하고 싶지 않습니다.

어떻게하면됩니까?

해결법

  1. ==============================

    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. ==============================

    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 등으로 저장하려는 모든 항목이 새 필드 유형에서 파생 된 것과 동일한 검사를 거치지는 않습니다.

  3. from https://stackoverflow.com/questions/8980735/how-can-i-verify-column-data-types-in-the-sqlalchemy-orm by cc-by-sa and MIT license