EnumCol

Not logged in - Log In / Register

/!\ This is out of date. The enum infrastructure was changed and db enums should no longer live in lp.dbschema, but in launchpad.interfaces. -- DavidAllouche 2007-11-14 16:52:36

dbschema.EnumCol

There is a new EnumCol type that you can use in database classes.

Use this column type where you would currently use an IntCol, and where the values in that column correspond to DBSchema values.

There's an example in lib/canonical/launchpad/database/bugtask.py

   1 from canonical.lp.dbschema import EnumCol
   2 from canonical.lp import dbschema
   3 ...
   4 
   5 class BugTask(SQLBase):
   6     implements(IBugTask)
   7     _table = "BugTask"
   8     _defaultOrder = "-bug"
   9 ...
  10     status = EnumCol(
  11         dbName='status', notNull=True,
  12         schema=dbschema.BugTaskStatus,
  13         default=dbschema.BugTaskStatus.NEW)
  14     priority = EnumCol(
  15         dbName='priority', notNull=True,
  16         schema=dbschema.BugPriority,
  17         default=dbschema.BugPriority.MEDIUM)
  18     severity = EnumCol(
  19         dbName='severity', notNull=True,
  20         schema=dbschema.BugSeverity,
  21         default=dbschema.BugSeverity.NORMAL)

Whenever you get something from an attribute defined by an EnumCol, it comes out as a DBSchema Item. Basically, on the "inside", the database side, the EnumCol gets and receives ints. On the "outside", the application code side, the EnumCol gets and receives DBSchema items.

You must always set DBSchema Items from the correct DBSchema class when you give that attribute new values.

The EnumCol works just like an IntCol, except that you must provide a schema keyword argument, giving the DBSchema you're using. You can allow NULL values by saying notNull=False. In that case, you can get or set None from this attribute. This is generally to be discouraged, and used only when the data model demands it. Always ask for a review if you think you need to do this.

When you're using a DBSchema class, you can get an item by name or by value like this:

    >>> from canonical.lp.dbschema import BugSeverity, Item

    We can iterate over the Items in a DBSchema class

    >>> for s in BugSeverity.items:
    ...     assert isinstance(s, Item)
    ...     print s.name
    ...
    WISHLIST
    MINOR
    NORMAL
    MAJOR
    CRITICAL

    We can retrieve an Item by value

    >>> BugSeverity.items[50].name
    'CRITICAL'

    We can also retrieve an Item by name.

    >>> BugSeverity.items['CRITICAL'].title
    'Critical'

Of course, you would never really use BugSeverity.items['CRITICAL'] in your code, just like that. You would use BugSeverity.CRITICAL instead. You would only use the .items[some_string_or_int] form when you have that string or int in a variable, and you need to convert it into the DBSchema item.

This is taken from lib/canonical/lp/tests/test_dbschema.py

There is no need to directly get the int value of a DBSchema item, like BugSeverity.CRITICAL.value, in regular application code. However, you may need to use this from code inside lib/canonical/launchpad/database/ when you want to write a complex SELECT statement. In that case, you can construct the string like 'SELECT foo FROM bar WHERE severity = %s' % BugSeverity.CRITICAL.value.

EnumCol (last edited 2009-07-29 15:59:52 by gary)