Skip to content
Advertisement

SqlAlchemy db.Enum: How to detect it and retrieve the values

I have a function to add a column to a model:

def col(_type, label = "", **kwargs):
    c = db.Column(_type, **kwargs)
    c.info = {"label":label, "type":""}
    return c
    

I use it like:

    # Job Type
    class JTEnum(enum.Enum):
       full = "ﺖﻣﺎﻣ ﻮﻘﺗ"
       part_time = "ﻦﯿﻤﻫ ﻮﻘﺗ"
       project = "ﭖﺭﻭﮋﻫ ﺎﯾ"

    jobtype = col(db.Enum(JTEnum), "ﻥﻮﻋ ﺶﻐﻟ", unique=False,
            nullable=False,
            default=JTEnum.full.name)
    jobtype.info["choices"] = [(i.name, i.value) for i in JTEnum]

I call the col function for various columns. I would like to put the last line inside this function and it can be called on Enum type and fill the choices something like:

def col(_type, label = "", **kwargs):
    c = db.Column(_type, **kwargs)
    c.info = {"label":label, "type":""}
    if isinstance(_type, db.Enum):
       c.info["choices"] = [(i.name, i.value) for i in _type]
    return c

However, it gives the error:

TypeError: 'Enum' object is not iterable

Advertisement

Answer

The first issue I’m seeing in your code is that you default to JTEnum.full.name, which should be the Enum element not its name, then you need to iterate the underlying Enum class of the SQLAlchemy Enum.

import enum

import sqlalchemy as db


class JTEnum(enum.Enum):
    full = "ﺖﻣﺎﻣ ﻮﻘﺗ"
    part_time = "ﻦﯿﻤﻫ ﻮﻘﺗ"
    project = "ﭖﺭﻭﮋﻫ ﺎﯾ"


def col(_type, label="", **kwargs):
    c = db.Column(_type, **kwargs)
    c.info = {"label": label, "type": ""}
    if isinstance(_type, db.Enum):
        c.info["choices"] = [(i.name, i.value) for i in _type.enum_class]
    return c


c = col(
    db.Enum(JTEnum),
    "ﻥﻮﻋ ﺶﻐﻟ",
    unique=False,
    nullable=False,
    default=JTEnum.full,
)

print(c.info)

# {'label': 'ﻥﻮﻋ ﺶﻐﻟ',
# 'type': '',
# 'choices': [('full', 'ﺖﻣﺎﻣ ﻮﻘﺗ'),
#  ('part_time', 'ﻦﯿﻤﻫ ﻮﻘﺗ'),
#  ('project', 'ﭖﺭﻭﮋﻫ ﺎﯾ')]}
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement