I have a very simple ChoiceString custom column/data type:
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] And I am iterating over the table columns using a 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 But I am can't seem to access the choices custom attribute of the custom type. I also tried "inspecting" the column directly instead of the class, but that doesn't work either.
So how do we access custom attributes of custom types in sqlalchemy, while inspecting?
2 Answers
You're inspecting the Column objects, not their types. Access the type through the type attribute of a Column object:
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'} 1The columns can be accessed through the __table__.columns collection. The type and the underlying python type can be accessed through col.type and cole.type.python_type, e.g:
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