How to "Inspect" Custom Types in Sqlalchemy

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'}
1

The 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.

Share this article
Twitter Facebook Pinterest