I have a database table that contains specific companies that are accessed "statically" throughout the code and for which would be great to have a "static" way to refer to them, for example:
from enum import Enum, auto()
class CompanyEnum(Enum):
APPLE = auto()
AMAZON = auto()
META = auto()
I would like the int value of the Enum to match the database id corresponding to those companies BUT of course I don't want the hardcoded id
in the static Enum definition as that would be a terrible solution. Why would that be a terrible solution? because there is no guarantee that if the database is recreated from a backup or re-generated, the artificial ids will remain the same for those companies.
I can do something like (assuming that I am using Peewee):
from functools import lru_cache
from enum import Enum, auto()
from models import Company
class CompanyEnum(Enum):
APPLE = auto()
AMAZON = auto()
META = auto()
@lru_cache
@property
def id(self):
company = Company.get(Company.name.upper() == self.name)
return company.id
How can I make this dynamically resolved id
property, the actual Enum int value?
The simplest solution is to get the names and ids with a function, and then use the functional API to to create the enum. Something like:
CompanyEnum = Enum('CompanyEnum', get_names_ids('company'))
and get_names_ids(column)
is something like:
def get_names_ids(column):
# talk to dbs and get values of id and column fields
return ... # [(id_1, company_1), (id_2, company_2), ...]
The get_names_ids
may have to ensure upper-case values, etc., but that's the basics.
Disclosure: I am the author of the Python stdlib Enum
, the enum34
backport, and the Advanced Enumeration (aenum
) library.