kvesteri / sqlalchemy-utils

Various utility functions and datatypes for SQLAlchemy.
Other
1.27k stars 321 forks source link

Support Enum for ChoiceType #116

Closed jacobsvante closed 2 years ago

jacobsvante commented 9 years ago

I really like the ChoiceType field, it would be nice though to have the values enforced on the db level as well with sqlalchemy.types.Enum as the underlying type. What do you think?

kvesteri commented 9 years ago

Yes this would require the choices to be passed to the underlying type (if its Enum). I think this would be a nice feature :+1:

bouzlibop commented 9 years ago

:+1: would be great to have that

vToMy commented 9 years ago

I'm currently using: http://techspot.zzzeek.org/2011/01/14/the-enum-recipe/ But I think being able to map python enum type to sqlalchemy.types.Enum would be best.

jacobsvante commented 8 years ago

To be clear the following works:


from sqlalchemy import Column, Enum
from .db import Base

class MyModel(Base):
    STATUS_CHOICES = (
        ('published', 'Published'),
        ('hidden', 'Hidden'),
    )
    STATUSES = tuple(c[0] for c in STATUS_CHOICES)

    status = Column(
        ChoiceType(impl=Enum(*STATUSES, name='mymodel_status'), choices=STATUS_CHOICES),
        default='published',
        nullable=False
    )

I'm not sure there could be any more clean way to do this. Can you?

Perhaps passing the kwargs of ChoiceType to the Enum. Like this:

ChoiceType(impl_class=Enum, name='mymodel_status', choices=STATUS_CHOICES)

# Would be turned into this:
impl = impl_class(*(c[0] for c in choices), **{'name': name})
ChoiceType(impl=impl, choices=choices)
dbanty commented 5 years ago

I would very much like this to happen. Currently if I have an enum.Enum that I want a model to use, I have these choices:

  1. Use the SQLAlchemy Enum type which will store the value as an Enum in the backing database (in my case MySQL). However, it will not type coerce to the Enum from a value for me which is very handy.
  2. Use ChoiceType, get my type coercion, but lose the backing tech
  3. Use the method pointed out by @jmagnusson above which gets me what I want but requires a bunch of extra code

I plan on going with option 3 for now so I can both have my cake and eat it, but it would be nice to make this the default behavior.

charlax commented 5 years ago

Looks like this is now supported?

https://sqlalchemy-utils.readthedocs.io/en/latest/data_types.html#module-sqlalchemy_utils.types.choice

kurtmckee commented 2 years ago

Agreed, this appears to be implemented. If not, please add a comment to clarify what has not been implemented. Thanks!