如何在sqlalchemy中“检查”自定义类型

时间:2017-07-27 07:43:19

标签: python sqlalchemy

我有一个非常简单的ChoiceString自定义列/数据类型:

class ChoiceString(types.TypeDecorator):

    impl = types.String

    def __init__(self, choices, **kw):
        self.choices = dict(choices)
        super(ChoiceString, self).__init__(**kw)

    def process_bind_param(self, value, dialect):
        return [k for k, v in self.choices.iteritems() if v == value][0]

    def process_result_value(self, value, dialect):
        return self.choices[value]

我使用mapper

迭代表格列
from sqlalchemy.inspection import inspect

mapper = inspect(SomeTableClass)

for col in mapper.columns:
    print col
    # how to check the choice values?
    print dir(mapper.columns[col])  # does not show the 'choices' attribute
    print dir(inspect(mapper.columns[col]))  # does not show the 'choices' attribute
    print mapper.columns[col].choices  # error

但我似乎无法访问自定义类型的choices自定义属性。我也尝试直接“检查”列而不是类,但这也不起作用。

那么在检查时我们如何在sqlalchemy中访问自定义类型的自定义属性?

2 个答案:

答案 0 :(得分:1)

您正在检查Column个对象,而不是它们的类型。通过type对象的Column属性访问该类型:

In [9]: class SomeTableClass(Base):
   ...:     __tablename__ = 'sometableclass'
   ...:     id = Column(Integer, primary_key=True)
   ...:     choices = Column(ChoiceString({ 'asdf': 'qwer'}))
   ...:     

In [10]: mapper = inspect(SomeTableClass)

In [12]: mapper.columns['choices']
Out[12]: Column('choices', ChoiceString(), table=<sometableclass>)

In [13]: mapper.columns['choices'].type.choices
Out[13]: {'asdf': 'qwer'}

答案 1 :(得分:0)

可以通过__table__.columns集合访问这些列。可以通过col.typecole.type.python_type访问类型和基础python类型,例如:

import enum

from sqlalchemy import Column, Enum, Integer, String, Text
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class Gender(enum.Enum):
    MALE = "male"
    FEMALE = "female"


class Person(Base):
    __tablename__ = "table_person"
    id = Column(Integer, primary_key=True)
    name = Column(String(20))
    gender = Column(Enum(Gender))
    address = Column(Text)


def test_inspect_columns():
    col_id = Person.__table__.columns["id"]
    assert isinstance(col_id.type, Integer)
    assert col_id.type.python_type is int

    col_name = Person.__table__.columns["name"]
    assert isinstance(col_name.type, String)
    assert col_name.type.python_type is str

    col_gender = Person.__table__.columns["gender"]
    assert isinstance(col_gender.type, Enum)
    assert col_gender.type.python_type is Gender

    col_address = Person.__table__.columns["address"]
    assert isinstance(col_address.type, Text)
    assert col_address.type.python_type is str