Use Unova's English name. #451
[zzz-pokedex.git] / pokedex / db / tables.py
index e01f43d..ab4c671 100644 (file)
@@ -38,7 +38,7 @@ metadata = MetaData()
 TableBase = declarative_base(metadata=metadata)
 
 class Ability(TableBase):
 TableBase = declarative_base(metadata=metadata)
 
 class Ability(TableBase):
-    """An ability a pokémon can have, such as Static or Pressure.
+    u"""An ability a pokémon can have, such as Static or Pressure.
     """
     __tablename__ = 'abilities'
     __singlename__ = 'ability'
     """
     __tablename__ = 'abilities'
     __singlename__ = 'ability'
@@ -54,7 +54,7 @@ class Ability(TableBase):
         info=dict(description="Short summary of this ability's effect", format='markdown'))
 
 class AbilityFlavorText(TableBase):
         info=dict(description="Short summary of this ability's effect", format='markdown'))
 
 class AbilityFlavorText(TableBase):
-    """In-game flavor text of an ability
+    u"""In-game flavor text of an ability
     """
     __tablename__ = 'ability_flavor_text'
     ability_id = Column(Integer, ForeignKey('abilities.id'), primary_key=True, nullable=False, autoincrement=False,
     """
     __tablename__ = 'ability_flavor_text'
     ability_id = Column(Integer, ForeignKey('abilities.id'), primary_key=True, nullable=False, autoincrement=False,
@@ -65,7 +65,7 @@ class AbilityFlavorText(TableBase):
         info=dict(description="The actual flavor text", official=True, format='gametext'))
 
 class AbilityName(TableBase):
         info=dict(description="The actual flavor text", official=True, format='gametext'))
 
 class AbilityName(TableBase):
-    """Non-English official name of an ability
+    u"""Non-English official name of an ability
     """
     __tablename__ = 'ability_names'
     ability_id = Column(Integer, ForeignKey('abilities.id'), primary_key=True, nullable=False, autoincrement=False,
     """
     __tablename__ = 'ability_names'
     ability_id = Column(Integer, ForeignKey('abilities.id'), primary_key=True, nullable=False, autoincrement=False,
@@ -76,7 +76,7 @@ class AbilityName(TableBase):
         info=dict(description="ID of the language", official=True, foreign=True, format='plaintext'))
 
 class Berry(TableBase):
         info=dict(description="ID of the language", official=True, foreign=True, format='plaintext'))
 
 class Berry(TableBase):
-    """A Berry, consumable item that grows on trees
+    u"""A Berry, consumable item that grows on trees
 
     For data common to all Items, such as the name, see the corresponding Item entry.
     """
 
     For data common to all Items, such as the name, see the corresponding Item entry.
     """
@@ -103,7 +103,7 @@ class Berry(TableBase):
         info=dict(description="Smoothness of this Berry, a culinary attribute. Higher is better."))
 
 class BerryFirmness(TableBase):
         info=dict(description="Smoothness of this Berry, a culinary attribute. Higher is better."))
 
 class BerryFirmness(TableBase):
-    """A Berry firmness, such as "hard" or "very soft".
+    u"""A Berry firmness, such as "hard" or "very soft".
     """
     __tablename__ = 'berry_firmness'
     id = Column(Integer, primary_key=True, nullable=False,
     """
     __tablename__ = 'berry_firmness'
     id = Column(Integer, primary_key=True, nullable=False,
@@ -112,7 +112,7 @@ class BerryFirmness(TableBase):
         info=dict(description="English name of the firmness level", official=True, format='plaintext'))
 
 class BerryFlavor(TableBase):
         info=dict(description="English name of the firmness level", official=True, format='plaintext'))
 
 class BerryFlavor(TableBase):
-    """A Berry flavor level.
+    u"""A Berry flavor level.
     """
     __tablename__ = 'berry_flavors'
     berry_id = Column(Integer, ForeignKey('berries.id'), primary_key=True, nullable=False, autoincrement=False,
     """
     __tablename__ = 'berry_flavors'
     berry_id = Column(Integer, ForeignKey('berries.id'), primary_key=True, nullable=False, autoincrement=False,
@@ -123,7 +123,7 @@ class BerryFlavor(TableBase):
         info=dict(description="Level of the flavor in the berry"))
 
 class ContestCombo(TableBase):
         info=dict(description="Level of the flavor in the berry"))
 
 class ContestCombo(TableBase):
-    """Combo of two moves in a Contest.
+    u"""Combo of two moves in a Contest.
     """
     __tablename__ = 'contest_combos'
     first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
     """
     __tablename__ = 'contest_combos'
     first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
@@ -132,7 +132,7 @@ class ContestCombo(TableBase):
         info=dict(description="ID of the second and final move in the combo"))
 
 class ContestEffect(TableBase):
         info=dict(description="ID of the second and final move in the combo"))
 
 class ContestEffect(TableBase):
-    """Effect of a move when used in a Contest.
+    u"""Effect of a move when used in a Contest.
     """
     __tablename__ = 'contest_effects'
     id = Column(Integer, primary_key=True, nullable=False,
     """
     __tablename__ = 'contest_effects'
     id = Column(Integer, primary_key=True, nullable=False,
@@ -147,7 +147,8 @@ class ContestEffect(TableBase):
         info=dict(description="Detailed description of the effect", format='markdown'))
 
 class ContestType(TableBase):
         info=dict(description="Detailed description of the effect", format='markdown'))
 
 class ContestType(TableBase):
-    u"""A Contest type, such as "cool" or "smart". Also functions as Berry flavor and Pokéblock color."""
+    u"""A Contest type, such as "cool" or "smart". Also functions as Berry flavor and Pokéblock color.
+    """
     __tablename__ = 'contest_types'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'contest_types'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -156,10 +157,10 @@ class ContestType(TableBase):
     flavor = Column(Unicode(6), nullable=False,
         info=dict(description="The English name of the corresponding Berry flavor", official=True, format='identifier'))
     color = Column(Unicode(6), nullable=False,
     flavor = Column(Unicode(6), nullable=False,
         info=dict(description="The English name of the corresponding Berry flavor", official=True, format='identifier'))
     color = Column(Unicode(6), nullable=False,
-        info=dict(description="The English name of the corresponding Pokéblock color", official=True, format='identifier'))
+        info=dict(description=u"The English name of the corresponding Pokéblock color", official=True, format='identifier'))
 
 class EggGroup(TableBase):
 
 class EggGroup(TableBase):
-    """An Egg group. Usually, two Pokémon can breed if they share an Egg Group.
+    u"""An Egg group. Usually, two Pokémon can breed if they share an Egg Group.
 
     (exceptions are the Ditto and No Eggs groups)
     """
 
     (exceptions are the Ditto and No Eggs groups)
     """
@@ -167,10 +168,10 @@ class EggGroup(TableBase):
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     name = Column(Unicode(16), nullable=False,
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     name = Column(Unicode(16), nullable=False,
-        info=dict(description="The English “official” name. One NPC in Stadium uses these names; they are pretty bad.", official=True, format='identifier'))
+        info=dict(description=u'The English "official" name. One NPC in Stadium uses these names; they are pretty bad.', official=True, format='identifier'))
 
 class Encounter(TableBase):
 
 class Encounter(TableBase):
-    """Encounters with wild Pokémon.
+    u"""Encounters with wild Pokémon.
 
     Bear with me, here.
 
 
     Bear with me, here.
 
@@ -210,7 +211,7 @@ class Encounter(TableBase):
         info=dict(description=u"The maxmum level of the encountered Pokémon"))
 
 class EncounterCondition(TableBase):
         info=dict(description=u"The maxmum level of the encountered Pokémon"))
 
 class EncounterCondition(TableBase):
-    """A conditions in the game world that affects pokémon encounters, such as time of day.
+    u"""A conditions in the game world that affects pokémon encounters, such as time of day.
     """
 
     __tablename__ = 'encounter_conditions'
     """
 
     __tablename__ = 'encounter_conditions'
@@ -220,7 +221,7 @@ class EncounterCondition(TableBase):
         info=dict(description="An English name of the condition", format='plaintext'))
 
 class EncounterConditionValue(TableBase):
         info=dict(description="An English name of the condition", format='plaintext'))
 
 class EncounterConditionValue(TableBase):
-    """A possible state for a condition; for example, the state of 'swarm' could be 'swarm' or 'no swarm'.
+    u"""A possible state for a condition; for example, the state of 'swarm' could be 'swarm' or 'no swarm'.
     """
 
     __tablename__ = 'encounter_condition_values'
     """
 
     __tablename__ = 'encounter_condition_values'
@@ -234,8 +235,8 @@ class EncounterConditionValue(TableBase):
         info=dict(description='Set if this value is "default" or "normal" in some sense'))
 
 class EncounterConditionValueMap(TableBase):
         info=dict(description='Set if this value is "default" or "normal" in some sense'))
 
 class EncounterConditionValueMap(TableBase):
-    """Maps encounters to the specific conditions under which they occur."""
-
+    u"""Maps encounters to the specific conditions under which they occur.
+    """
     __tablename__ = 'encounter_condition_value_map'
     encounter_id = Column(Integer, ForeignKey('encounters.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="ID of the encounter"))
     __tablename__ = 'encounter_condition_value_map'
     encounter_id = Column(Integer, ForeignKey('encounters.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="ID of the encounter"))
@@ -243,7 +244,7 @@ class EncounterConditionValueMap(TableBase):
         info=dict(description="ID of the encounter condition value"))
 
 class EncounterTerrain(TableBase):
         info=dict(description="ID of the encounter condition value"))
 
 class EncounterTerrain(TableBase):
-    """A way the player can enter a wild encounter, e.g., surfing, fishing, or walking through tall grass.
+    u"""A way the player can enter a wild encounter, e.g., surfing, fishing, or walking through tall grass.
     """
 
     __tablename__ = 'encounter_terrain'
     """
 
     __tablename__ = 'encounter_terrain'
@@ -253,7 +254,7 @@ class EncounterTerrain(TableBase):
         info=dict(description="An english name of this terrain", format='plaintext'))
 
 class EncounterSlot(TableBase):
         info=dict(description="An english name of this terrain", format='plaintext'))
 
 class EncounterSlot(TableBase):
-    """Aan abstract "slot" within a terrain, associated with both some set of conditions and a rarity.
+    u"""An abstract "slot" within a terrain, associated with both some set of conditions and a rarity.
 
     Note that there are two encounters per slot, so the rarities will only add
     up to 50.
 
     Note that there are two encounters per slot, so the rarities will only add
     up to 50.
@@ -266,14 +267,14 @@ class EncounterSlot(TableBase):
         info=dict(description="The ID of the Version group this slot is in"))
     encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=False, nullable=False, autoincrement=False,
         info=dict(description="The ID of the terrain"))
         info=dict(description="The ID of the Version group this slot is in"))
     encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=False, nullable=False, autoincrement=False,
         info=dict(description="The ID of the terrain"))
-    slot = Column(Integer, nullable=True)
-        # XXX: What is this?
+    slot = Column(Integer, nullable=True,
+        info=dict(description="The slot")) # XXX: What is this, exactly?
     rarity = Column(Integer, nullable=False,
         info=dict(description="The chance of the encounter, in percent"))  # XXX: It is in percent, right? I'm confused.
 
 class EncounterSlotCondition(TableBase):
     rarity = Column(Integer, nullable=False,
         info=dict(description="The chance of the encounter, in percent"))  # XXX: It is in percent, right? I'm confused.
 
 class EncounterSlotCondition(TableBase):
-    """A condition that affects an encounter slot."""
-
+    u"""A condition that affects an encounter slot.
+    """
     __tablename__ = 'encounter_slot_conditions'
     encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the encounter slot"))
     __tablename__ = 'encounter_slot_conditions'
     encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the encounter slot"))
@@ -281,7 +282,8 @@ class EncounterSlotCondition(TableBase):
         info=dict(description="The ID of the encounter condition"))
 
 class EvolutionChain(TableBase):
         info=dict(description="The ID of the encounter condition"))
 
 class EvolutionChain(TableBase):
-    """A family of pokémon that are linked by evolution"""
+    u"""A family of pokémon that are linked by evolution
+    """
     __tablename__ = 'evolution_chains'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'evolution_chains'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -291,7 +293,8 @@ class EvolutionChain(TableBase):
         info=dict(description="Item that a parent must hold while breeding to produce a baby"))
 
 class EvolutionTrigger(TableBase):
         info=dict(description="Item that a parent must hold while breeding to produce a baby"))
 
 class EvolutionTrigger(TableBase):
-    """An evolution type, such as "level" or "trade"."""
+    u"""An evolution type, such as "level" or "trade".
+    """
     __tablename__ = 'evolution_triggers'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'evolution_triggers'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -299,7 +302,8 @@ class EvolutionTrigger(TableBase):
         info=dict(description="An English identifier", format='identifier'))
 
 class Experience(TableBase):
         info=dict(description="An English identifier", format='identifier'))
 
 class Experience(TableBase):
-    """EXP needed for a certain level with a certain growth rate"""
+    u"""EXP needed for a certain level with a certain growth rate
+    """
     __tablename__ = 'experience'
     growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), primary_key=True, nullable=False,
         info=dict(description="ID of the growth rate"))
     __tablename__ = 'experience'
     growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), primary_key=True, nullable=False,
         info=dict(description="ID of the growth rate"))
@@ -309,7 +313,8 @@ class Experience(TableBase):
         info=dict(description="The number of EXP points needed to get to that level"))
 
 class Generation(TableBase):
         info=dict(description="The number of EXP points needed to get to that level"))
 
 class Generation(TableBase):
-    u"""A Generation of the pokémon franchise"""
+    u"""A Generation of the pokémon franchise
+    """
     __tablename__ = 'generations'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'generations'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -321,7 +326,8 @@ class Generation(TableBase):
         info=dict(description=u'An English name of this generation, such as "Generation IV"', format='plaintext'))
 
 class GrowthRate(TableBase):
         info=dict(description=u'An English name of this generation, such as "Generation IV"', format='plaintext'))
 
 class GrowthRate(TableBase):
-    u"""Growth rate of a pokémon, i.e. the EXP → level function."""
+    u"""Growth rate of a pokémon, i.e. the EXP → level function.
+    """
     __tablename__ = 'growth_rates'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'growth_rates'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -331,7 +337,8 @@ class GrowthRate(TableBase):
         info=dict(description="The formula", format='latex'))
 
 class Item(TableBase):
         info=dict(description="The formula", format='latex'))
 
 class Item(TableBase):
-    """An Item from the games, like "Poké Ball" or "Bicycle"."""
+    u"""An Item from the games, like "Poké Ball" or "Bicycle".
+    """
     __tablename__ = 'items'
     __singlename__ = 'item'
     id = Column(Integer, primary_key=True, nullable=False,
     __tablename__ = 'items'
     __singlename__ = 'item'
     id = Column(Integer, primary_key=True, nullable=False,
@@ -351,11 +358,13 @@ class Item(TableBase):
 
     @property
     def appears_underground(self):
 
     @property
     def appears_underground(self):
-        """True if the item appears underground, as specified by the appropriate flag"""
+        u"""True if the item appears underground, as specified by the appropriate flag
+        """
         return any(flag.identifier == u'underground' for flag in self.flags)
 
 class ItemCategory(TableBase):
         return any(flag.identifier == u'underground' for flag in self.flags)
 
 class ItemCategory(TableBase):
-    """An item category"""
+    u"""An item category
+    """
     # XXX: This is fanon, right?
     __tablename__ = 'item_categories'
     id = Column(Integer, primary_key=True, nullable=False,
     # XXX: This is fanon, right?
     __tablename__ = 'item_categories'
     id = Column(Integer, primary_key=True, nullable=False,
@@ -366,7 +375,8 @@ class ItemCategory(TableBase):
         info=dict(description="English name of the category", format='plaintext'))
 
 class ItemFlag(TableBase):
         info=dict(description="English name of the category", format='plaintext'))
 
 class ItemFlag(TableBase):
-    """An item attribute such as "consumable" or "holdable"."""
+    u"""An item attribute such as "consumable" or "holdable".
+    """
     __tablename__ = 'item_flags'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'item_flags'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -376,7 +386,8 @@ class ItemFlag(TableBase):
         info=dict(description="Short English description of the flag", format='plaintext'))
 
 class ItemFlagMap(TableBase):
         info=dict(description="Short English description of the flag", format='plaintext'))
 
 class ItemFlagMap(TableBase):
-    """Maps an item flag to its item."""
+    u"""Maps an item flag to its item.
+    """
     __tablename__ = 'item_flag_map'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="The ID of the item"))
     __tablename__ = 'item_flag_map'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="The ID of the item"))
@@ -384,7 +395,8 @@ class ItemFlagMap(TableBase):
         info=dict(description="The ID of the item flag"))
 
 class ItemFlavorText(TableBase):
         info=dict(description="The ID of the item flag"))
 
 class ItemFlavorText(TableBase):
-    """An in-game description of an item"""
+    u"""An in-game description of an item
+    """
     __tablename__ = 'item_flavor_text'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="The ID of the item"))
     __tablename__ = 'item_flavor_text'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="The ID of the item"))
@@ -394,7 +406,8 @@ class ItemFlavorText(TableBase):
         info=dict(description="The flavor text itself", official=True, format='gametext'))
 
 class ItemFlingEffect(TableBase):
         info=dict(description="The flavor text itself", official=True, format='gametext'))
 
 class ItemFlingEffect(TableBase):
-    """An effect of the move Fling when used with a specific item"""
+    u"""An effect of the move Fling when used with a specific item
+    """
     __tablename__ = 'item_fling_effects'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'item_fling_effects'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -402,7 +415,8 @@ class ItemFlingEffect(TableBase):
         info=dict(description="English description of the effect", format='plaintext'))
 
 class ItemInternalID(TableBase):
         info=dict(description="English description of the effect", format='plaintext'))
 
 class ItemInternalID(TableBase):
-    """The internal ID number a game uses for an item"""
+    u"""The internal ID number a game uses for an item
+    """
     __tablename__ = 'item_internal_ids'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="The database ID of the item"))
     __tablename__ = 'item_internal_ids'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="The database ID of the item"))
@@ -412,7 +426,8 @@ class ItemInternalID(TableBase):
         info=dict(description="Internal ID of the item in the generation"))
 
 class ItemName(TableBase):
         info=dict(description="Internal ID of the item in the generation"))
 
 class ItemName(TableBase):
-    """A non-English name of an item"""
+    u"""A non-English name of an item
+    """
     __tablename__ = 'item_names'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the item"))
     __tablename__ = 'item_names'
     item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the item"))
@@ -422,7 +437,8 @@ class ItemName(TableBase):
         info=dict(description="The name of the item in this language", foreign=True, format='plaintext'))
 
 class ItemPocket(TableBase):
         info=dict(description="The name of the item in this language", foreign=True, format='plaintext'))
 
 class ItemPocket(TableBase):
-    """A pocket that categorizes items"""
+    u"""A pocket that categorizes items
+    """
     __tablename__ = 'item_pockets'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'item_pockets'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -432,7 +448,8 @@ class ItemPocket(TableBase):
         info=dict(description="A numeric ID", format='plaintext'))
 
 class Language(TableBase):
         info=dict(description="A numeric ID", format='plaintext'))
 
 class Language(TableBase):
-    u"""A language the Pokémon games have been transleted into; except English"""
+    u"""A language the Pokémon games have been transleted into; except English
+    """
     __tablename__ = 'languages'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     __tablename__ = 'languages'
     id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
@@ -444,130 +461,234 @@ class Language(TableBase):
         info=dict(description="The English name of the language", format='plaintext'))
 
 class Location(TableBase):
         info=dict(description="The English name of the language", format='plaintext'))
 
 class Location(TableBase):
+    u"""A place in the Pokémon world
+    """
     __tablename__ = 'locations'
     __singlename__ = 'location'
     __tablename__ = 'locations'
     __singlename__ = 'location'
-    id = Column(Integer, primary_key=True, nullable=False)
-    region_id = Column(Integer, ForeignKey('regions.id'))
-    name = Column(Unicode(64), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    region_id = Column(Integer, ForeignKey('regions.id'),
+        info=dict(description="ID of the region this location is in"))
+    name = Column(Unicode(64), nullable=False,
+        info=dict(description="English name of the location", official=True, format='plaintext'))
 
 class LocationArea(TableBase):
 
 class LocationArea(TableBase):
+    u"""A sub-area of a location
+    """
     __tablename__ = 'location_areas'
     __tablename__ = 'location_areas'
-    id = Column(Integer, primary_key=True, nullable=False)
-    location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
-    internal_id = Column(Integer, nullable=False)
-    name = Column(Unicode(64), nullable=True)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    location_id = Column(Integer, ForeignKey('locations.id'), nullable=False,
+        info=dict(description="ID of the location this area is part of"))
+    internal_id = Column(Integer, nullable=False,
+        info=dict(description="ID the games ude for this area"))
+    name = Column(Unicode(64), nullable=True,
+        info=dict(description="An English name of the area, if applicable", format='plaintext'))
 
 class LocationAreaEncounterRate(TableBase):
 
 class LocationAreaEncounterRate(TableBase):
+    # XXX: What's this exactly? Someone add the docstring & revise the descriptions
     __tablename__ = 'location_area_encounter_rates'
     __tablename__ = 'location_area_encounter_rates'
-    location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
-    encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
-    version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, autoincrement=False)
-    rate = Column(Integer, nullable=True)
+    location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the area"))
+    encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the terrain"))
+    version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, autoincrement=False,
+        info=dict(description="ID of the version"))
+    rate = Column(Integer, nullable=True,
+        info=dict(description="The encounter rate"))  # units?
 
 class LocationInternalID(TableBase):
 
 class LocationInternalID(TableBase):
+    u"""IDs the games use internally for locations
+    """
     __tablename__ = 'location_internal_ids'
     __tablename__ = 'location_internal_ids'
-    location_id = Column(Integer, ForeignKey('locations.id'), nullable=False, primary_key=True)
-    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False, primary_key=True)
-    internal_id = Column(Integer, nullable=False)
+    location_id = Column(Integer, ForeignKey('locations.id'), nullable=False, primary_key=True,
+        info=dict(description="Database ID of the locaion"))
+    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False, primary_key=True,
+        info=dict(description="ID of the generation this entry to"))
+    internal_id = Column(Integer, nullable=False,
+        info=dict(description="Internal game ID of the location"))
 
 class Machine(TableBase):
 
 class Machine(TableBase):
+    u"""A TM or HM; numbered item that can teach a move to a pokémon
+    """
     __tablename__ = 'machines'
     __tablename__ = 'machines'
-    machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
-    item_id = Column(Integer, ForeignKey('items.id'), nullable=False)
-    move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
+    machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="Number of the machine for TMs, or 100 + the munber for HMs"))
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="Versions this entry applies to"))
+    item_id = Column(Integer, ForeignKey('items.id'), nullable=False,
+        info=dict(description="ID of the corresponding Item"))
+    move_id = Column(Integer, ForeignKey('moves.id'), nullable=False,
+        info=dict(description="ID of the taught move"))
 
     @property
     def is_hm(self):
 
     @property
     def is_hm(self):
+        u"""True if this machine is a HM, False if it's a TM
+        """
         return self.machine_number >= 100
 
 class MoveBattleStyle(TableBase):
         return self.machine_number >= 100
 
 class MoveBattleStyle(TableBase):
+    u"""A battle style of a move"""  # XXX: Explain better
     __tablename__ = 'move_battle_styles'
     __tablename__ = 'move_battle_styles'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(8), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(8), nullable=False,
+        info=dict(description="An English name for this battle style", format='plaintext'))
 
 class MoveEffectCategory(TableBase):
 
 class MoveEffectCategory(TableBase):
+    u"""Category of a move effect
+    """
     __tablename__ = 'move_effect_categories'
     __tablename__ = 'move_effect_categories'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(64), nullable=False)
-    can_affect_user = Column(Boolean, nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(64), nullable=False,
+        info=dict(description="English name of the category", format='plaintext'))
+    can_affect_user = Column(Boolean, nullable=False,
+        info=dict(description="Set if the user can be affected"))
 
 class MoveEffectCategoryMap(TableBase):
 
 class MoveEffectCategoryMap(TableBase):
+    u"""Maps a move effect category to a move effect
+    """
     __tablename__ = 'move_effect_category_map'
     __tablename__ = 'move_effect_category_map'
-    move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False)
-    move_effect_category_id = Column(Integer, ForeignKey('move_effect_categories.id'), primary_key=True, nullable=False)
-    affects_user = Column(Boolean, primary_key=True, nullable=False)
+    move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False,
+        info=dict(description="ID of the move effect"))
+    move_effect_category_id = Column(Integer, ForeignKey('move_effect_categories.id'), primary_key=True, nullable=False,
+        info=dict(description="ID of the category"))
+    affects_user = Column(Boolean, primary_key=True, nullable=False,
+        info=dict(description="Set if the user is affected"))
 
 class MoveDamageClass(TableBase):
 
 class MoveDamageClass(TableBase):
+    u"""Damage class of a move, i.e. "Physical", "Special, or "None".
+    """
     __tablename__ = 'move_damage_classes'
     __tablename__ = 'move_damage_classes'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(8), nullable=False)
-    description = Column(Unicode(64), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(8), nullable=False,
+        info=dict(description="An English name of the class", format='plaintext'))
+    description = Column(Unicode(64), nullable=False,
+        info=dict(description="An English description of the class", format='plaintext'))
 
 class MoveEffect(TableBase):
 
 class MoveEffect(TableBase):
+    u"""An effect of a move
+    """
     __tablename__ = 'move_effects'
     __tablename__ = 'move_effects'
-    id = Column(Integer, primary_key=True, nullable=False)
-    short_effect = Column(Unicode(256), nullable=False)
-    effect = Column(Unicode(5120), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    short_effect = Column(Unicode(256), nullable=False,
+        info=dict(description="A short summary of the effect", format='plaintext'))
+    effect = Column(Unicode(5120), nullable=False,
+        info=dict(description="A detailed description of the effect", format='plaintext'))
 
 class MoveFlag(TableBase):
 
 class MoveFlag(TableBase):
+    u"""Maps a move flag to a move
+    """
+    # XXX: Other flags have a ___Flag class for the actual flag and ___FlagMap for the map,
+    # these, somewhat confusingly, have MoveFlagType and MoveFlag
     __tablename__ = 'move_flags'
     __tablename__ = 'move_flags'
-    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
-    move_flag_type_id = Column(Integer, ForeignKey('move_flag_types.id'), primary_key=True, nullable=False, autoincrement=False)
+    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the move"))
+    move_flag_type_id = Column(Integer, ForeignKey('move_flag_types.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the flag"))
 
 class MoveFlagType(TableBase):
 
 class MoveFlagType(TableBase):
+    u"""A Move attribute such as "snatchable" or "contact".
+    """
     __tablename__ = 'move_flag_types'
     __tablename__ = 'move_flag_types'
-    id = Column(Integer, primary_key=True, nullable=False)
-    identifier = Column(Unicode(16), nullable=False)
-    name = Column(Unicode(32), nullable=False)
-    description = Column(markdown.MarkdownColumn(128), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    identifier = Column(Unicode(16), nullable=False,
+        info=dict(description="A short identifier for the flag", format='identifier'))
+    name = Column(Unicode(32), nullable=False,
+        info=dict(description="An English name for the flag", format='plaintext'))
+    description = Column(markdown.MarkdownColumn(128), nullable=False,
+        info=dict(description="A short English description of the flag", format='markdown'))
 
 class MoveFlavorText(TableBase):
 
 class MoveFlavorText(TableBase):
+    u"""In-game description of a move
+    """
     __tablename__ = 'move_flavor_text'
     __tablename__ = 'move_flavor_text'
-    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
-    flavor_text = Column(Unicode(255), nullable=False)
+    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the move"))
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the version group this text appears in"))
+    flavor_text = Column(Unicode(255), nullable=False,
+        info=dict(description="The English flavor text", official=True, format='gametext'))
 
 class MoveName(TableBase):
 
 class MoveName(TableBase):
+    u"""Non-English name of a move
+    """
     __tablename__ = 'move_names'
     __tablename__ = 'move_names'
-    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(16), nullable=False)
+    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the move"))
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the language"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description="ID of the language", foreign=True, format='plaintext'))
 
 class MoveTarget(TableBase):
 
 class MoveTarget(TableBase):
+    u"""Targetting or "range" of a move, e.g. "Affects all opponents" or "Affects user".
+    """
     __tablename__ = 'move_targets'
     __tablename__ = 'move_targets'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(32), nullable=False)
-    description = Column(Unicode(128), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(32), nullable=False,
+        info=dict(description="An English name", format='plaintext'))
+    description = Column(Unicode(128), nullable=False,
+        info=dict(description="An English description", format='plaintext'))
 
 class Move(TableBase):
 
 class Move(TableBase):
+    u"""A Move: technique or attack a Pokémon can learn to use
+    """
     __tablename__ = 'moves'
     __singlename__ = 'move'
     __tablename__ = 'moves'
     __singlename__ = 'move'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(24), nullable=False)
-    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
-    type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
-    power = Column(SmallInteger, nullable=False)
-    pp = Column(SmallInteger, nullable=False)
-    accuracy = Column(SmallInteger, nullable=True)
-    priority = Column(SmallInteger, nullable=False)
-    target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False)
-    damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False)
-    effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False)
-    effect_chance = Column(Integer)
-    contest_type_id = Column(Integer, ForeignKey('contest_types.id'), nullable=True)
-    contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True)
-    super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=True)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(24), nullable=False,
+        info=dict(description="The English name of the move", official=True, format='plaintext'))
+    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False,
+        info=dict(description="ID of the generation this move first appeared in"))
+    type_id = Column(Integer, ForeignKey('types.id'), nullable=False,
+        info=dict(description="ID of the move's elemental type"))
+    power = Column(SmallInteger, nullable=False,
+        info=dict(description="Base power of the move"))
+    pp = Column(SmallInteger, nullable=False,
+        info=dict(description="Base PP (Power Points) of the move"))
+    accuracy = Column(SmallInteger, nullable=True,
+        info=dict(description="Accuracy of the move; NULL means it never misses"))
+    priority = Column(SmallInteger, nullable=False,
+        info=dict(description="The move's priority bracket"))
+    target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False,
+        info=dict(description="ID of the target (range) of the move"))
+    damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False,
+        info=dict(description="ID of the damage class (physical/special) of the move"))
+    effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False,
+        info=dict(description="ID of the move's effect"))
+    effect_chance = Column(Integer,
+        info=dict(description="The chance for a secondary effect. What this is a chance of is specified by the move's effect."))
+    contest_type_id = Column(Integer, ForeignKey('contest_types.id'), nullable=True,
+        info=dict(description="ID of the move's Contest type (e.g. cool or smart)"))
+    contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True,
+        info=dict(description="ID of the move's Contest effect"))
+    super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=True,
+        info=dict(description="ID of the move's Super Contest effect"))
 
 class Nature(TableBase):
 
 class Nature(TableBase):
+    u"""A nature a pokémon can have, such as Calm or Brave
+    """
     __tablename__ = 'natures'
     __singlename__ = 'nature'
     __tablename__ = 'natures'
     __singlename__ = 'nature'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(8), nullable=False)
-    decreased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False)
-    increased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False)
-    hates_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False)
-    likes_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(8), nullable=False,
+        info=dict(description="An English name of the nature", official=True, format='plaintext'))
+    decreased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False,
+        info=dict(description="ID of the stat that this nature decreases by 10% (if decreased_stat_id is the same, the effects cancel out)"))
+    increased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False,
+        info=dict(description="ID of the stat that this nature increases by 10% (if decreased_stat_id is the same, the effects cancel out)"))
+    hates_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False,
+        info=dict(description=u"ID of the Berry flavor the Pokémon hates (if likes_flavor_id is the same, the effects cancel out)"))
+    likes_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False,
+        info=dict(description=u"ID of the Berry flavor the Pokémon likes (if hates_flavor_id is the same, the effects cancel out)"))
 
     @property
     def is_neutral(self):
 
     @property
     def is_neutral(self):
@@ -577,108 +698,161 @@ class Nature(TableBase):
         return self.increased_stat_id == self.decreased_stat_id
 
 class NatureBattleStylePreference(TableBase):
         return self.increased_stat_id == self.decreased_stat_id
 
 class NatureBattleStylePreference(TableBase):
+    u"""Battle Palace move preference
+
+    Specifies how likely a pokémon with a specific Nature is to use a move of
+    a particular battl style in Battle Palace or Battle Tent
+    """
     __tablename__ = 'nature_battle_style_preferences'
     __tablename__ = 'nature_battle_style_preferences'
-    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False)
-    move_battle_style_id = Column(Integer, ForeignKey('move_battle_styles.id'), primary_key=True, nullable=False)
-    low_hp_preference = Column(Integer, nullable=False)
-    high_hp_preference = Column(Integer, nullable=False)
+    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False,
+        info=dict(description=u"ID of the pokémon's nature"))
+    move_battle_style_id = Column(Integer, ForeignKey('move_battle_styles.id'), primary_key=True, nullable=False,
+        info=dict(description="ID of the battle style"))
+    low_hp_preference = Column(Integer, nullable=False,
+        info=dict(description=u"Chance of using the move, in percent, if HP is under ½"))
+    high_hp_preference = Column(Integer, nullable=False,
+        info=dict(description=u"Chance of using the move, in percent, if HP is over ½"))
 
 class NatureName(TableBase):
 
 class NatureName(TableBase):
+    u"""Non-english name of a Nature
+    """
     __tablename__ = 'nature_names'
     __tablename__ = 'nature_names'
-    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False, autoincrement=False)
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(8), nullable=False)
+    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the nature"))
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the language"))
+    name = Column(Unicode(8), nullable=False,
+        info=dict(description="The nature's foreign name", foreign=True, format='plaintext'))
 
 class NaturePokeathlonStat(TableBase):
 
 class NaturePokeathlonStat(TableBase):
+    u"""Specifies how a Nature affects a Pokéathlon stat
+    """
     __tablename__ = 'nature_pokeathlon_stats'
     __tablename__ = 'nature_pokeathlon_stats'
-    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False)
-    pokeathlon_stat_id = Column(Integer, ForeignKey('pokeathlon_stats.id'), primary_key=True, nullable=False)
-    max_change = Column(Integer, nullable=False)
+    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False,
+        info=dict(description="ID of the nature"))
+    pokeathlon_stat_id = Column(Integer, ForeignKey('pokeathlon_stats.id'), primary_key=True, nullable=False,
+        info=dict(description="ID of the stat"))
+    max_change = Column(Integer, nullable=False,
+        info=dict(description="Maximum change"))
 
 class PokeathlonStat(TableBase):
 
 class PokeathlonStat(TableBase):
+    u"""A Pokéathlon stat, such as "Stamina" or "Jump".
+    """
     __tablename__ = 'pokeathlon_stats'
     __tablename__ = 'pokeathlon_stats'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(8), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    name = Column(Unicode(8), nullable=False,
+        info=dict(description="The English name of the stat", official=True, format='plaintext'))
 
 class Pokedex(TableBase):
 
 class Pokedex(TableBase):
+    u"""A collection of pokémon species ordered in a particular way
+    """
     __tablename__ = 'pokedexes'
     __tablename__ = 'pokedexes'
-    id = Column(Integer, primary_key=True, nullable=False)
-    region_id = Column(Integer, ForeignKey('regions.id'), nullable=True)
-    name = Column(Unicode(16), nullable=False)
-    description = Column(Unicode(512))
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A numeric ID"))
+    region_id = Column(Integer, ForeignKey('regions.id'), nullable=True,
+        info=dict(description=u"ID of the region this pokédex is used in, or None if it's global"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"An English name of the pokédex", format='plaintext'))
+    description = Column(Unicode(512),
+        info=dict(description=u"A longer description of the pokédex", format='plaintext'))
 
 class PokedexVersionGroup(TableBase):
 
 class PokedexVersionGroup(TableBase):
+    u"""Maps a pokédex to the version group that uses it
+    """
     __tablename__ = 'pokedex_version_groups'
     __tablename__ = 'pokedex_version_groups'
-    pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
+    pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokédex"))
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the version group"))
 
 class Pokemon(TableBase):
 
 class Pokemon(TableBase):
-    """The core to this whole mess.
-
-    Note that I use both 'forme' and 'form' in both code and the database.  I
-    only use 'forme' when specifically referring to Pokémon that have multiple
-    distinct species as forms—i.e., different stats or movesets.  'Form' is a
-    more general term referring to any variation within a species, including
-    purely cosmetic forms like Unown.
+    u"""A species of Pokémon.  The core to this whole mess.
     """
     __tablename__ = 'pokemon'
     __singlename__ = 'pokemon'
     """
     __tablename__ = 'pokemon'
     __singlename__ = 'pokemon'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(20), nullable=False)
-    forme_name = Column(Unicode(16))
-    forme_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
-    generation_id = Column(Integer, ForeignKey('generations.id'))
-    evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'))
-    height = Column(Integer, nullable=False)
-    weight = Column(Integer, nullable=False)
-    species = Column(Unicode(16), nullable=False)
-    color_id = Column(Integer, ForeignKey('pokemon_colors.id'), nullable=False)
-    pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=True)
-    habitat_id = Column(Integer, ForeignKey('pokemon_habitats.id'), nullable=True)
-    gender_rate = Column(Integer, nullable=False)
-    capture_rate = Column(Integer, nullable=False)
-    base_experience = Column(Integer, nullable=False)
-    base_happiness = Column(Integer, nullable=False)
-    is_baby = Column(Boolean, nullable=False)
-    hatch_counter = Column(Integer, nullable=False)
-    has_gen4_fem_sprite = Column(Boolean, nullable=False)
-    has_gen4_fem_back_sprite = Column(Boolean, nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    name = Column(Unicode(20), nullable=False,
+        info=dict(description=u"The English name of the Pokémon", official=True, format='plaintext'))
+    generation_id = Column(Integer, ForeignKey('generations.id'),
+        info=dict(description=u"ID of the generation this species first appeared in"))
+    evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'),
+        info=dict(description=u"ID of the species' evolution chain (a.k.a. family)"))
+    height = Column(Integer, nullable=False,
+        info=dict(description=u"The height of the pokémon, in decimeters (tenths of a meter)"))
+    weight = Column(Integer, nullable=False,
+        info=dict(description=u"The weight of the pokémon, in tenths of a kilogram (decigrams)"))
+    species = Column(Unicode(16), nullable=False,
+        info=dict(description=u'The short English flavor text, such as "Seed" or "Lizard"; usually affixed with the word "Pokémon"',
+        official=True, format='plaintext'))
+    color_id = Column(Integer, ForeignKey('pokemon_colors.id'), nullable=False,
+        info=dict(description=u"ID of this pokémon's pokédex color, as used for a gimmick search function in the games."))
+    pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=True,
+        info=dict(description=u"ID of this pokémon's body shape, as used for a gimmick search function in the games."))
+    habitat_id = Column(Integer, ForeignKey('pokemon_habitats.id'), nullable=True,
+        info=dict(description=u"ID of this pokémon's habitat, as used for a gimmick search function in the games."))
+    gender_rate = Column(Integer, nullable=False,
+        info=dict(description=u"The chance of this pokémon being female, in eighths; or -1 for genderless"))
+    capture_rate = Column(Integer, nullable=False,
+        info=dict(description=u"The base capture rate; up to 255"))
+    base_experience = Column(Integer, nullable=False,
+        info=dict(description=u"The base EXP gained when defeating this pokémon"))  # XXX: Is this correct?
+    base_happiness = Column(Integer, nullable=False,
+        info=dict(description=u"The tameness when caught by a normal ball"))
+    is_baby = Column(Boolean, nullable=False,
+        info=dict(description=u"True iff the pokémon is a baby"))  # XXX: What exactly makes it a baby?
+    hatch_counter = Column(Integer, nullable=False,
+        info=dict(description=u"Initial hatch counter: one must walk 255 × (hatch_counter + 1) steps before this pokémon's egg hatches, unless utilizing bonuses like Flame Body's"))
+    has_gen4_fem_sprite = Column(Boolean, nullable=False,
+        info=dict(description=u"Set iff the species' female front sprite is different from the male's in generation IV"))
+    has_gen4_fem_back_sprite = Column(Boolean, nullable=False,
+        info=dict(description=u"Set iff the species' female back sprite is different from the male's in generation IV"))
 
     ### Stuff to handle alternate Pokémon forms
 
     @property
 
     ### Stuff to handle alternate Pokémon forms
 
     @property
-    def national_id(self):
-        """Returns the National Pokédex number for this Pokémon.  Use this
-        instead of the id directly; alternate formes may make the id incorrect.
+    def is_base_form(self):
+        u"""Returns True iff the Pokémon is the base form for its species,
+        e.g. Land Shaymin.
+        """
+
+        return self.unique_form is None or self.unique_form.is_default
+
+    @property
+    def form_name(self):
+        u"""Returns the Pokémon's form name if it represents a particular form
+        and that form has a name, or None otherwise.
         """
 
         """
 
-        if self.forme_base_pokemon_id:
-            return self.forme_base_pokemon_id
-        return self.id
+        # If self.unique_form is None, the short-circuit "and" will go ahead
+        # and return that.  Otherwise, it'll return the form's name, which may
+        # also be None.
+        return self.unique_form and self.unique_form.name
 
     @property
     def full_name(self):
 
     @property
     def full_name(self):
-        """Returns the name of this Pokémon, including its Forme, if any."""
+        u"""Returns the Pokémon's name, including its form if applicable."""
 
 
-        if self.forme_name:
-            return "%s %s" % (self.forme_name.title(), self.name)
-        return self.name
+        if self.form_name:
+            return '{0} {1}'.format(self.form_name, self.name)
+        else:
+            return self.name
 
     @property
     def normal_form(self):
 
     @property
     def normal_form(self):
-        """Returns the normal form for this Pokémon; i.e., this will return
+        u"""Returns the normal form for this Pokémon; i.e., this will return
         regular Deoxys when called on any Deoxys form.
         """
 
         regular Deoxys when called on any Deoxys form.
         """
 
-        if self.forme_base_pokemon:
-            return self.forme_base_pokemon
-
+        if self.unique_form:
+            return self.unique_form.form_base_pokemon
         return self
 
     ### Not forms!
 
     def stat(self, stat_name):
         return self
 
     ### Not forms!
 
     def stat(self, stat_name):
-        """Returns a PokemonStat record for the given stat name (or Stat row
+        u"""Returns a PokemonStat record for the given stat name (or Stat row
         object).  Uses the normal has-many machinery, so all the stats are
         effectively cached.
         """
         object).  Uses the normal has-many machinery, so all the stats are
         effectively cached.
         """
@@ -712,90 +886,214 @@ class Pokemon(TableBase):
             return None
 
 class PokemonAbility(TableBase):
             return None
 
 class PokemonAbility(TableBase):
+    u"""Maps an ability to a pokémon that can have it
+    """
     __tablename__ = 'pokemon_abilities'
     __tablename__ = 'pokemon_abilities'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False)
-    slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False,
+        info=dict(description=u"ID of the ability"))
+    # XXX having both a method and a slot is kind of gross.  "slot" is a
+    # misnomer, anyway: duplicate abilities don't appear in slot 2.
+    # Probably should replace that with "order".
+    is_dream = Column(Boolean, nullable=False, index=True,
+        info=dict(description=u"Whether this is a Dream World ability"))
+    slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"The ability slot, i.e. 1 or 2 for gen. IV"))
 
 class PokemonColor(TableBase):
 
 class PokemonColor(TableBase):
+    u"""The "pokédex color" of a pokémon species. Usually based on the pokémon's color.
+    """
     __tablename__ = 'pokemon_colors'
     __tablename__ = 'pokemon_colors'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(6), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    name = Column(Unicode(6), nullable=False,
+        info=dict(description=u"The English name of the color", official=True, format='identifier'))
 
 class PokemonDexNumber(TableBase):
 
 class PokemonDexNumber(TableBase):
+    u"""The number of a Pokémon in a particular Pokédex (e.g. Jigglypuff is #138 in Hoenn's 'dex)
+    """
     __tablename__ = 'pokemon_dex_numbers'
     __tablename__ = 'pokemon_dex_numbers'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
-    pokedex_number = Column(Integer, nullable=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokédex"))
+    pokedex_number = Column(Integer, nullable=False,
+        info=dict(description=u"Number of the pokémon in that the pokédex"))
 
 class PokemonEggGroup(TableBase):
 
 class PokemonEggGroup(TableBase):
+    u"""Maps an Egg group to a pokémon; each pokémon belongs to one or two egg groups
+    """
     __tablename__ = 'pokemon_egg_groups'
     __tablename__ = 'pokemon_egg_groups'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the egg group"))
 
 class PokemonEvolution(TableBase):
 
 class PokemonEvolution(TableBase):
+    u"""Specifies what causes a particular pokémon to evolve into another species.
+    """
     __tablename__ = 'pokemon_evolution'
     __tablename__ = 'pokemon_evolution'
-    from_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False)
-    to_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    evolution_trigger_id = Column(Integer, ForeignKey('evolution_triggers.id'), nullable=False)
-    trigger_item_id = Column(Integer, ForeignKey('items.id'), nullable=True)
-    minimum_level = Column(Integer, nullable=True)
-    gender = Column(Enum('male', 'female', name='pokemon_evolution_gender'), nullable=True)
-    location_id = Column(Integer, ForeignKey('locations.id'), nullable=True)
-    held_item_id = Column(Integer, ForeignKey('items.id'), nullable=True)
-    time_of_day = Column(Enum('morning', 'day', 'night', name='pokemon_evolution_time_of_day'), nullable=True)
-    known_move_id = Column(Integer, ForeignKey('moves.id'), nullable=True)
-    minimum_happiness = Column(Integer, nullable=True)
-    minimum_beauty = Column(Integer, nullable=True)
-    relative_physical_stats = Column(Integer, nullable=True)
-    party_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=True)
+    from_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False,
+        info=dict(description=u"ID of the pre-evolution species"))
+    to_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the post-evolution species"))
+    evolution_trigger_id = Column(Integer, ForeignKey('evolution_triggers.id'), nullable=False,
+        info=dict(description=u"ID of the trigger type"))
+    trigger_item_id = Column(Integer, ForeignKey('items.id'), nullable=True,
+        info=dict(description=u"ID of the item that triggers the evolution in a way defined by evolution_trigger_id"))
+    minimum_level = Column(Integer, nullable=True,
+        info=dict(description=u"Minimum level, or None if level doean't matter"))
+    gender = Column(Enum('male', 'female', name='pokemon_evolution_gender'), nullable=True,
+        info=dict(description=u"Required gender, or None if gender doesn't matter"))
+    location_id = Column(Integer, ForeignKey('locations.id'), nullable=True,
+        info=dict(description=u"Required location, or None if it doesn't matter"))
+    held_item_id = Column(Integer, ForeignKey('items.id'), nullable=True,
+        info=dict(description=u"An item the pokémon must hold, or None if it doesn't matter"))
+    time_of_day = Column(Enum('morning', 'day', 'night', name='pokemon_evolution_time_of_day'), nullable=True,
+        info=dict(description=u"Required time of day, or None if it doesn't matter"))
+    known_move_id = Column(Integer, ForeignKey('moves.id'), nullable=True,
+        info=dict(description=u"ID of a move the pokémon must know, or None if it doesn't matter"))
+    minimum_happiness = Column(Integer, nullable=True,
+        info=dict(description=u"Minimum tameness value the pokémon must have, or None if it doesn't matter"))
+    minimum_beauty = Column(Integer, nullable=True,
+        info=dict(description=u"Minimum Beauty value the pokémon must have, or None if it doesn't matter"))
+    relative_physical_stats = Column(Integer, nullable=True,
+        info=dict(description=u"Relation of Attack and Defense stats the pokémon must have, as sgn(atk-def), or None if that doesn't matter"))
+    party_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=True,
+        info=dict(description=u"ID of a pokémon that must be present in the party, or None if there's no such condition"))
 
 class PokemonFlavorText(TableBase):
 
 class PokemonFlavorText(TableBase):
+    u"""In-game pokédex descrption of a pokémon.
+    """
     __tablename__ = 'pokemon_flavor_text'
     __tablename__ = 'pokemon_flavor_text'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
-    flavor_text = Column(Unicode(255), nullable=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the version that has this flavor text"))
+    flavor_text = Column(Unicode(255), nullable=False,
+        info=dict(description=u"ID of the version that has this flavor text", official=True, format='gametext'))
+
+class PokemonForm(TableBase):
+    u"""An individual form of a Pokémon.
+
+    Pokémon that do not have separate forms are still given a single row to
+    represent their single form.
+    """
+    __tablename__ = 'pokemon_forms'
+    __singlename__ = 'pokemon_form'
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u'A unique ID for this form.'))
+    name = Column(Unicode(16), nullable=True,
+        info=dict(description=u"This form's name, e.g. \"Plant\" for Plant Cloak Burmy.", official=True, format='plaintext'))
+    form_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False,
+        info=dict(description=u'The ID of the base Pokémon for this form.'))
+    unique_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), autoincrement=False,
+        info=dict(description=u'The ID of a Pokémon that represents specifically this form, for Pokémon with functionally-different forms like Wormadam.'))
+    introduced_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), autoincrement=False,
+        info=dict(description=u'The ID of the version group in which this form first appeared.'))
+    is_default = Column(Boolean, nullable=False,
+        info=dict(description=u'Set for exactly one form used as the default for each species.'))
+    order = Column(Integer, nullable=False, autoincrement=False,
+        info=dict(description=u'The order in which forms should be sorted.  Multiple forms may have equal order, in which case they should fall back on sorting by name.'))
+
+    @property
+    def full_name(self):
+        u"""Returns the full name of this form, e.g. "Plant Cloak"."""
+
+        if not self.name:
+            return None
+        elif self.form_group and self.form_group.term:
+            return '{0} {1}'.format(self.name, self.form_group.term)
+        else:
+            return self.name
+
+    @property
+    def pokemon_name(self):
+        u"""Returns the name of this Pokémon with this form, e.g. "Plant
+        Burmy".
+        """
+
+        if self.name:
+            return '{0} {1}'.format(self.name, self.form_base_pokemon.name)
+        else:
+            return self.form_base_pokemon.name
 
 class PokemonFormGroup(TableBase):
 
 class PokemonFormGroup(TableBase):
+    u"""Information about a Pokémon's forms as a group."""
     __tablename__ = 'pokemon_form_groups'
     __tablename__ = 'pokemon_form_groups'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    is_battle_only = Column(Boolean, nullable=False)
-    description = Column(markdown.MarkdownColumn(1024), nullable=False)
-
-class PokemonFormSprite(TableBase):
-    __tablename__ = 'pokemon_form_sprites'
-    id = Column(Integer, primary_key=True, nullable=False)
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    introduced_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(16), nullable=True)
-    is_default = Column(Boolean, nullable=True)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the base form Pokémon"))
+    term = Column(Unicode(16), nullable=True,
+        info=dict(description=u"The term for this Pokémon's forms, e.g. \"Cloak\" for Burmy or \"Forme\" for Deoxys.", official=True, format='plaintext'))
+    is_battle_only = Column(Boolean, nullable=False,
+        info=dict(description=u"Set iff the forms only change in battle"))
+    description = Column(markdown.MarkdownColumn(1024), nullable=False,
+        info=dict(description=u"English description of how the forms work", format='markdown'))
+
+class PokemonFormPokeathlonStat(TableBase):
+    u"""A Pokémon form's performance in one Pokéathlon stat."""
+    __tablename__ = 'pokemon_form_pokeathlon_stats'
+    pokemon_form_id = Column(Integer, ForeignKey('pokemon_forms.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u'The ID of the Pokémon form.'))
+    pokeathlon_stat_id = Column(Integer, ForeignKey('pokeathlon_stats.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u'The ID of the Pokéathlon stat.'))
+    minimum_stat = Column(Integer, nullable=False, autoincrement=False,
+        info=dict(description=u'The minimum value for this stat for this Pokémon form.'))
+    base_stat = Column(Integer, nullable=False, autoincrement=False,
+        info=dict(description=u'The default value for this stat for this Pokémon form.'))
+    maximum_stat = Column(Integer, nullable=False, autoincrement=False,
+        info=dict(description=u'The maximum value for this stat for this Pokémon form.'))
 
 class PokemonHabitat(TableBase):
 
 class PokemonHabitat(TableBase):
+    u"""The habitat of a pokémon, as given in the FireRed/LeafGreen version pokédex
+    """
     __tablename__ = 'pokemon_habitats'
     __tablename__ = 'pokemon_habitats'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(16), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"A numeric ID"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"The English name of the habitat", official=True, format='plaintext'))
 
 class PokemonInternalID(TableBase):
 
 class PokemonInternalID(TableBase):
+    u"""The number of a pokémon a game uses internally
+    """
     __tablename__ = 'pokemon_internal_ids'
     __tablename__ = 'pokemon_internal_ids'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, autoincrement=False, nullable=False)
-    generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, autoincrement=False, nullable=False)
-    internal_id = Column(Integer, nullable=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, autoincrement=False, nullable=False,
+        info=dict(description=u"Database ID of the pokémon"))
+    generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, autoincrement=False, nullable=False,
+        info=dict(description=u"Database ID of the generation"))
+    internal_id = Column(Integer, nullable=False,
+        info=dict(description=u"Internal ID the generation's games use for the pokémon"))
 
 class PokemonItem(TableBase):
 
 class PokemonItem(TableBase):
+    u"""Record of an item a pokémon can hold in the wild
+    """
     __tablename__ = 'pokemon_items'
     __tablename__ = 'pokemon_items'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
-    item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False)
-    rarity = Column(Integer, nullable=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the version this applies to"))
+    item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the item"))
+    rarity = Column(Integer, nullable=False,
+        info=dict(description=u"Chance of the pokémon holding the item, in percent"))
 
 class PokemonMove(TableBase):
 
 class PokemonMove(TableBase):
+    u"""Record of a move a pokémon can learn
+    """
     __tablename__ = 'pokemon_moves'
     __tablename__ = 'pokemon_moves'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, index=True)
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, index=True)
-    move_id = Column(Integer, ForeignKey('moves.id'), nullable=False, index=True)
-    pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), nullable=False, index=True)
-    level = Column(Integer, nullable=True, index=True)
-    order = Column(Integer, nullable=True)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, index=True,
+        info=dict(description=u"ID of the pokémon"))
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, index=True,
+        info=dict(description=u"ID of the version group this applies to"))
+    move_id = Column(Integer, ForeignKey('moves.id'), nullable=False, index=True,
+        info=dict(description=u"ID of the move"))
+    pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), nullable=False, index=True,
+        info=dict(description=u"ID of the method this move is learned by"))
+    level = Column(Integer, nullable=True, index=True,
+        info=dict(description=u"Level the move is learned at, if applicable"))
+    order = Column(Integer, nullable=True,
+        info=dict(description=u"A sort key to produce the correct ordering when all else is equal"))  # XXX: This needs a better description
 
     __table_args__ = (
         PrimaryKeyConstraint('pokemon_id', 'version_group_id', 'move_id', 'pokemon_move_method_id', 'level'),
 
     __table_args__ = (
         PrimaryKeyConstraint('pokemon_id', 'version_group_id', 'move_id', 'pokemon_move_method_id', 'level'),
@@ -803,101 +1101,177 @@ class PokemonMove(TableBase):
     )
 
 class PokemonMoveMethod(TableBase):
     )
 
 class PokemonMoveMethod(TableBase):
+    u"""A method a move can be learned by, such as "Level up" or "Tutor".
+    """
     __tablename__ = 'pokemon_move_methods'
     __tablename__ = 'pokemon_move_methods'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(64), nullable=False)
-    description = Column(Unicode(255), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"A numeric ID"))
+    name = Column(Unicode(64), nullable=False,
+        info=dict(description=u"An English name of the method", format='plaintext'))
+    description = Column(Unicode(255), nullable=False,
+        info=dict(description=u"A detailed description of how the method works", format='plaintext'))
 
 class PokemonName(TableBase):
 
 class PokemonName(TableBase):
+    u"""A non-English name of a pokémon.
+    """
     __tablename__ = 'pokemon_names'
     __tablename__ = 'pokemon_names'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(16), nullable=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the language"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"Name of the pokémon in the language", foreign=True, format='plaintext'))
 
 class PokemonShape(TableBase):
 
 class PokemonShape(TableBase):
+    u"""The shape of a pokémon's body, as used in generation IV pokédexes.
+    """
     __tablename__ = 'pokemon_shapes'
     __tablename__ = 'pokemon_shapes'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(24), nullable=False)
-    awesome_name = Column(Unicode(16), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    name = Column(Unicode(24), nullable=False,
+        info=dict(description=u"A boring English name of the body shape", format='plaintext'))
+    awesome_name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"A splendiferous, technically English, name of the body shape", format='plaintext'))
 
 class PokemonStat(TableBase):
 
 class PokemonStat(TableBase):
+    u"""A stat value of a pokémon
+    """
     __tablename__ = 'pokemon_stats'
     __tablename__ = 'pokemon_stats'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False)
-    base_stat = Column(Integer, nullable=False)
-    effort = Column(Integer, nullable=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the stat"))
+    base_stat = Column(Integer, nullable=False,
+        info=dict(description=u"The base stat"))
+    effort = Column(Integer, nullable=False,
+        info=dict(description=u"The effort increase in this stat gained when this pokémon is defeated"))
 
 class PokemonType(TableBase):
 
 class PokemonType(TableBase):
+    u"""Maps a type to a pokémon. Each pokémon has 1 or 2 types.
+    """
     __tablename__ = 'pokemon_types'
     __tablename__ = 'pokemon_types'
-    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
-    type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
-    slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
+    pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the pokémon"))
+    type_id = Column(Integer, ForeignKey('types.id'), nullable=False,
+        info=dict(description=u"ID of the type"))
+    slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"The type's slot, 1 or 2, used to sort types if there are two of them"))
 
 class Region(TableBase):
 
 class Region(TableBase):
-    """Major areas of the world: Kanto, Johto, etc."""
+    u"""Major areas of the world: Kanto, Johto, etc.
+    """
     __tablename__ = 'regions'
     __tablename__ = 'regions'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(16), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"The English name of the region", official=True, format='plaintext'))
 
 class Stat(TableBase):
 
 class Stat(TableBase):
+    u"""A Stat, such as Attack or Speed
+    """
     __tablename__ = 'stats'
     __tablename__ = 'stats'
-    id = Column(Integer, primary_key=True, nullable=False)
-    damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=True)
-    name = Column(Unicode(16), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=True,
+        info=dict(description=u"For offensive and defensive stats, the damage this stat relates to; otherwise None (the NULL value)"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"The English name of the stat", official=True, format='plaintext'))
 
 class SuperContestCombo(TableBase):
 
 class SuperContestCombo(TableBase):
+    u"""Combo of two moves in a Super Contest.
+    """
     __tablename__ = 'super_contest_combos'
     __tablename__ = 'super_contest_combos'
-    first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
-    second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
+    first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the first move"))
+    second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the second and last move"))
 
 class SuperContestEffect(TableBase):
 
 class SuperContestEffect(TableBase):
+    u"""An effect a move can have when used in the Super Contest
+    """
     __tablename__ = 'super_contest_effects'
     __tablename__ = 'super_contest_effects'
-    id = Column(Integer, primary_key=True, nullable=False)
-    appeal = Column(SmallInteger, nullable=False)
-    flavor_text = Column(Unicode(64), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    appeal = Column(SmallInteger, nullable=False,
+        info=dict(description=u"Number of hearts the user will get when executing a move with this effect"))
+    flavor_text = Column(Unicode(64), nullable=False,
+        info=dict(description=u"An English description of the effect", format='plaintext'))
 
 class TypeEfficacy(TableBase):
 
 class TypeEfficacy(TableBase):
+    u"""The effectiveness of damage of one type against pokémon of another type
+    """
     __tablename__ = 'type_efficacy'
     __tablename__ = 'type_efficacy'
-    damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
-    target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
-    damage_factor = Column(Integer, nullable=False)
+    damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the damage type; most commonly this is the same as the attack type"))
+    target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the defending pokémon's type"))
+    damage_factor = Column(Integer, nullable=False,
+        info=dict(description=u"The effectiveness, in percent"))
 
 class Type(TableBase):
 
 class Type(TableBase):
+    u"""An elemental type, such as Grass or Steel
+    """
     __tablename__ = 'types'
     __singlename__ = 'type'
     __tablename__ = 'types'
     __singlename__ = 'type'
-    id = Column(Integer, primary_key=True, nullable=False)
-    name = Column(Unicode(8), nullable=False)
-    abbreviation = Column(Unicode(3), nullable=False)
-    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
-    damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False) ## ??? is none; everything else is physical or special
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    name = Column(Unicode(8), nullable=False,
+        info=dict(description=u"The English name.", format='plaintext'))  # XXX: Is this official? The games don't spell "Electric" in full...
+    abbreviation = Column(Unicode(3), nullable=False,
+        info=dict(description=u"An arbitrary 3-letter abbreviation of the type", format='plaintext'))  # XXX: Or is it not arbitrary?
+    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False,
+        info=dict(description=u"ID of the generation this type first appeared in"))
+    damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False,
+        info=dict(description=u"ID of the damage class this type's moves had before generation IV, or None for the ??? type"))
 
 class TypeName(TableBase):
 
 class TypeName(TableBase):
+    u"""Non-English name of an elemental type
+    """
     __tablename__ = 'type_names'
     __tablename__ = 'type_names'
-    type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
-    name = Column(Unicode(16), nullable=False)
+    type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the type"))
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description=u"ID of the language"))
+    name = Column(Unicode(16), nullable=False,
+        info=dict(description=u"Name of the type in that language", foreign=True, format='plaintext'))
 
 class VersionGroup(TableBase):
 
 class VersionGroup(TableBase):
+    u"""A group of related game versions
+    """
     __tablename__ = 'version_groups'
     __tablename__ = 'version_groups'
-    id = Column(Integer, primary_key=True, nullable=False)
-    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False,
+        info=dict(description=u"ID of the generation the games of this group belong to"))
 
 class VersionGroupRegion(TableBase):
 
 class VersionGroupRegion(TableBase):
+    u"""Maps a region to a game version group that features it
+    """
     __tablename__ = 'version_group_regions'
     __tablename__ = 'version_group_regions'
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False)
-    region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False)
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False,
+        info=dict(description=u"ID of the version"))
+    region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False,
+        info=dict(description=u"ID of the region"))
 
 class Version(TableBase):
 
 class Version(TableBase):
+    u"""A version of a mainline pokémon game
+    """
     __tablename__ = 'versions'
     __tablename__ = 'versions'
-    id = Column(Integer, primary_key=True, nullable=False)
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False)
-    name = Column(Unicode(32), nullable=False)
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False,
+        info=dict(description=u"ID of the version group this game belongs to"))
+    name = Column(Unicode(32), nullable=False,
+        info=dict(description=u'The English name of the game, without the "Pokémon" prefix', official=True, format='plaintext'))
 
 
 ### Relations down here, to avoid ordering problems
 Ability.flavor_text = relation(AbilityFlavorText, order_by=AbilityFlavorText.version_group_id, backref='ability')
 Ability.foreign_names = relation(AbilityName, backref='ability')
 Ability.generation = relation(Generation, backref='abilities')
 
 
 ### Relations down here, to avoid ordering problems
 Ability.flavor_text = relation(AbilityFlavorText, order_by=AbilityFlavorText.version_group_id, backref='ability')
 Ability.foreign_names = relation(AbilityName, backref='ability')
 Ability.generation = relation(Generation, backref='abilities')
+Ability.pokemon = relation(Pokemon,
+    secondary=PokemonAbility.__table__,
+)
 
 AbilityFlavorText.version_group = relation(VersionGroup)
 
 
 AbilityFlavorText.version_group = relation(VersionGroup)
 
@@ -1031,21 +1405,29 @@ NaturePokeathlonStat.pokeathlon_stat = relation(PokeathlonStat, backref='nature_
 Pokedex.region = relation(Region, backref='pokedexes')
 Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__, backref='pokedexes')
 
 Pokedex.region = relation(Region, backref='pokedexes')
 Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__, backref='pokedexes')
 
-Pokemon.abilities = relation(Ability, secondary=PokemonAbility.__table__,
-                                      order_by=PokemonAbility.slot,
-                                      backref='pokemon')
-Pokemon.formes = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.forme_base_pokemon_id,
-                                               backref=backref('forme_base_pokemon',
-                                                               remote_side=[Pokemon.id]))
+Pokemon.all_abilities = relation(Ability,
+    secondary=PokemonAbility.__table__,
+    order_by=PokemonAbility.slot,
+)
+Pokemon.abilities = relation(Ability,
+    secondary=PokemonAbility.__table__,
+    primaryjoin=and_(
+        Pokemon.id == PokemonAbility.pokemon_id,
+        PokemonAbility.is_dream == False,
+    ),
+    order_by=PokemonAbility.slot,
+)
+Pokemon.dream_ability = relation(Ability,
+    secondary=PokemonAbility.__table__,
+    primaryjoin=and_(
+        Pokemon.id == PokemonAbility.pokemon_id,
+        PokemonAbility.is_dream == True,
+    ),
+    uselist=False,
+)
 Pokemon.pokemon_color = relation(PokemonColor, backref='pokemon')
 Pokemon.color = association_proxy('pokemon_color', 'name')
 Pokemon.dex_numbers = relation(PokemonDexNumber, order_by=PokemonDexNumber.pokedex_id.asc(), backref='pokemon')
 Pokemon.pokemon_color = relation(PokemonColor, backref='pokemon')
 Pokemon.color = association_proxy('pokemon_color', 'name')
 Pokemon.dex_numbers = relation(PokemonDexNumber, order_by=PokemonDexNumber.pokedex_id.asc(), backref='pokemon')
-Pokemon.default_form_sprite = relation(PokemonFormSprite,
-                                       primaryjoin=and_(
-                                            Pokemon.id==PokemonFormSprite.pokemon_id,
-                                            PokemonFormSprite.is_default==True,
-                                       ),
-                                       uselist=False)
 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
                                         order_by=PokemonEggGroup.egg_group_id,
                                         backref='pokemon')
 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
                                         order_by=PokemonEggGroup.egg_group_id,
                                         backref='pokemon')
@@ -1058,13 +1440,19 @@ Pokemon.child_pokemon = relation(Pokemon,
 )
 Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.version_id.asc(), backref='pokemon')
 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
 )
 Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.version_id.asc(), backref='pokemon')
 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
+Pokemon.forms = relation(PokemonForm, primaryjoin=Pokemon.id==PokemonForm.form_base_pokemon_id,
+                         order_by=(PokemonForm.order.asc(), PokemonForm.name.asc()))
+Pokemon.default_form = relation(PokemonForm,
+    primaryjoin=and_(Pokemon.id==PokemonForm.form_base_pokemon_id, PokemonForm.is_default==True),
+    uselist=False,
+)
 Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
 Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
 Pokemon.items = relation(PokemonItem, backref='pokemon')
 Pokemon.generation = relation(Generation, backref='pokemon')
 Pokemon.shape = relation(PokemonShape, backref='pokemon')
 Pokemon.stats = relation(PokemonStat, backref='pokemon', order_by=PokemonStat.stat_id.asc())
 Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
 Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
 Pokemon.items = relation(PokemonItem, backref='pokemon')
 Pokemon.generation = relation(Generation, backref='pokemon')
 Pokemon.shape = relation(PokemonShape, backref='pokemon')
 Pokemon.stats = relation(PokemonStat, backref='pokemon', order_by=PokemonStat.stat_id.asc())
-Pokemon.types = relation(Type, secondary=PokemonType.__table__, order_by=PokemonType.slot.asc())
+Pokemon.types = relation(Type, secondary=PokemonType.__table__, order_by=PokemonType.slot.asc(), backref='pokemon')
 
 PokemonDexNumber.pokedex = relation(Pokedex)
 
 
 PokemonDexNumber.pokedex = relation(Pokedex)
 
@@ -1102,13 +1490,22 @@ PokemonEvolution.party_pokemon = relation(Pokemon,
 
 PokemonFlavorText.version = relation(Version)
 
 
 PokemonFlavorText.version = relation(Version)
 
-PokemonItem.item = relation(Item, backref='pokemon')
-PokemonItem.version = relation(Version)
+PokemonForm.form_base_pokemon = relation(Pokemon, primaryjoin=PokemonForm.form_base_pokemon_id==Pokemon.id)
+PokemonForm.unique_pokemon = relation(Pokemon, backref=backref('unique_form', uselist=False),
+                                      primaryjoin=PokemonForm.unique_pokemon_id==Pokemon.id)
+PokemonForm.version_group = relation(VersionGroup)
+PokemonForm.form_group = association_proxy('form_base_pokemon', 'form_group')
+PokemonForm.pokeathlon_stats = relation(PokemonFormPokeathlonStat,
+                                        order_by=PokemonFormPokeathlonStat.pokeathlon_stat_id,
+                                        backref='pokemon_form')
 
 PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
                                                              uselist=False))
 
 PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
                                                              uselist=False))
-PokemonFormSprite.pokemon = relation(Pokemon, backref='form_sprites')
-PokemonFormSprite.introduced_in = relation(VersionGroup)
+
+PokemonFormPokeathlonStat.pokeathlon_stat = relation(PokeathlonStat)
+
+PokemonItem.item = relation(Item, backref='pokemon')
+PokemonItem.version = relation(Version)
 
 PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
 PokemonMove.version_group = relation(VersionGroup)
 
 PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
 PokemonMove.version_group = relation(VersionGroup)