SQL Alchemy 枚举验证与验证函数冲突
SQL Alchemy enum validation conflict with validate function
我正在尝试使用 sqlalchemy enum 类型而不创建本机 DB ENUM 列,但仍然让 sqlalchemy 验证枚举输入。
所以我有这个声明:
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import Enum as SaEnum
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import validates
import enum
Base = declarative_base()
class DummyEnum(enum.Enum):
NAME_1 = "NAME_1"
NAME_2 = "NAME_2"
class SAEnumVarcharTable(Base):
__tablename__ = "test_table"
id = Column(Integer, primary_key=True)
uut_column = Column(SaEnum(DummyEnum, native_enum=False, validate_strings=True), default=DummyEnum.NAME_1)
@validates('uut_column')
def validate_uut_column(self, key, uut_value):
return uut_value.upper()
我想要验证 return 大写字符串,然后才进行枚举验证...
可能吗?
因为当我这样做时 :
connection.execute(insert(SAEnumVarcharTable), {"uut_column" : "name_1"})
它确实引发了一个 LookupError
我希望被接受为有效输入的地方(首先进入验证函数 -> return 一个大写字符串 -> 进行枚举验证)。 .有可能吗?
验证器仅在修改实例的属性时调用,例如:
instance = SAEnumVarcharTable()
instance.uut_column = "name_1"
在您的情况下,您需要覆盖 sqlalchemy.Enum
的 _db_value_for_elem
:
class UpperCaseEnum(SaEnum):
def _db_value_for_elem(self, elem):
return super()._db_value_for_elem(elem.upper())
# uut_column = Column(SaEnum(...), ...)
uut_column = Column(UpperCaseEnum(...), ...)
放在一边
验证器实现
validate_uut_column
未正确实施。
instance = SAEnumVarcharTable()
instance.uut_column = "name_0" # No error, expected LookupError
instance.uut_column = "name_1" # Ok
print(instance.uut_column == DummyEnum.NAME_1) # False, expected True
print(instance.uut_column.value == "NAME_1") # AttributeError: 'str' object has no attribute 'value'
instance.uut_column = DummyEnum.NAME_1 # AttributeError: 'DummyEnum' object has no attribute 'upper'
相反,它应该是:
@validates('uut_column')
def validate_uut_column(self, key, uut_value):
# return uut_value.upper()
return uut_value if uut_value in DummyEnum else DummyEnum[uut_value.upper()]
instance = SAEnumVarcharTable()
instance.uut_column = "name_0" # LookupError, as expected
instance.uut_column = "name_1" # Ok
print(instance.uut_column == DummyEnum.NAME_1) # True, as expected
print(instance.uut_column.value == "NAME_1") # True, as expected
instance.validate_uut_column = DummyEnum.NAME_1 # Ok
我正在尝试使用 sqlalchemy enum 类型而不创建本机 DB ENUM 列,但仍然让 sqlalchemy 验证枚举输入。
所以我有这个声明:
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import Enum as SaEnum
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import validates
import enum
Base = declarative_base()
class DummyEnum(enum.Enum):
NAME_1 = "NAME_1"
NAME_2 = "NAME_2"
class SAEnumVarcharTable(Base):
__tablename__ = "test_table"
id = Column(Integer, primary_key=True)
uut_column = Column(SaEnum(DummyEnum, native_enum=False, validate_strings=True), default=DummyEnum.NAME_1)
@validates('uut_column')
def validate_uut_column(self, key, uut_value):
return uut_value.upper()
我想要验证 return 大写字符串,然后才进行枚举验证... 可能吗?
因为当我这样做时 :
connection.execute(insert(SAEnumVarcharTable), {"uut_column" : "name_1"})
它确实引发了一个 LookupError
我希望被接受为有效输入的地方(首先进入验证函数 -> return 一个大写字符串 -> 进行枚举验证)。 .有可能吗?
验证器仅在修改实例的属性时调用,例如:
instance = SAEnumVarcharTable()
instance.uut_column = "name_1"
在您的情况下,您需要覆盖 sqlalchemy.Enum
的 _db_value_for_elem
:
class UpperCaseEnum(SaEnum):
def _db_value_for_elem(self, elem):
return super()._db_value_for_elem(elem.upper())
# uut_column = Column(SaEnum(...), ...)
uut_column = Column(UpperCaseEnum(...), ...)
放在一边
验证器实现
validate_uut_column
未正确实施。
instance = SAEnumVarcharTable()
instance.uut_column = "name_0" # No error, expected LookupError
instance.uut_column = "name_1" # Ok
print(instance.uut_column == DummyEnum.NAME_1) # False, expected True
print(instance.uut_column.value == "NAME_1") # AttributeError: 'str' object has no attribute 'value'
instance.uut_column = DummyEnum.NAME_1 # AttributeError: 'DummyEnum' object has no attribute 'upper'
相反,它应该是:
@validates('uut_column')
def validate_uut_column(self, key, uut_value):
# return uut_value.upper()
return uut_value if uut_value in DummyEnum else DummyEnum[uut_value.upper()]
instance = SAEnumVarcharTable()
instance.uut_column = "name_0" # LookupError, as expected
instance.uut_column = "name_1" # Ok
print(instance.uut_column == DummyEnum.NAME_1) # True, as expected
print(instance.uut_column.value == "NAME_1") # True, as expected
instance.validate_uut_column = DummyEnum.NAME_1 # Ok