Make Pokemon.form an actual relation
[zzz-pokedex.git] / pokedex / db / tables.py
index d9905b6..9553349 100644 (file)
@@ -32,7 +32,7 @@ from sqlalchemy.ext.associationproxy import association_proxy
 from sqlalchemy.orm import backref, relation
 from sqlalchemy.orm.session import Session
 from sqlalchemy.orm.interfaces import AttributeExtension
 from sqlalchemy.orm import backref, relation
 from sqlalchemy.orm.session import Session
 from sqlalchemy.orm.interfaces import AttributeExtension
-from sqlalchemy.sql import and_
+from sqlalchemy.sql import and_, or_
 from sqlalchemy.schema import ColumnDefault
 from sqlalchemy.types import *
 
 from sqlalchemy.schema import ColumnDefault
 from sqlalchemy.types import *
 
@@ -62,6 +62,9 @@ class TableSuperclass(object):
     def __str__(self):
         return unicode(self).encode('utf8')
 
     def __str__(self):
         return unicode(self).encode('utf8')
 
+    def __repr__(self):
+        return unicode(self).encode('utf8')
+
 mapped_classes = []
 class TableMetaclass(DeclarativeMeta):
     def __init__(cls, name, bases, attrs):
 mapped_classes = []
 class TableMetaclass(DeclarativeMeta):
     def __init__(cls, name, bases, attrs):
@@ -81,7 +84,7 @@ class Language(TableBase):
     """
     __tablename__ = 'languages'
     __singlename__ = 'language'
     """
     __tablename__ = 'languages'
     __singlename__ = 'language'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     iso639 = Column(Unicode(2), nullable=False,
         info=dict(description="The two-letter code of the country where this language is spoken. Note that it is not unique.", format='identifier'))
         info=dict(description="A numeric ID"))
     iso639 = Column(Unicode(2), nullable=False,
         info=dict(description="The two-letter code of the country where this language is spoken. Note that it is not unique.", format='identifier'))
@@ -108,7 +111,7 @@ class Ability(TableBase):
     """
     __tablename__ = 'abilities'
     __singlename__ = 'ability'
     """
     __tablename__ = 'abilities'
     __singlename__ = 'ability'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="This ability's unique ID; matches the games' internal ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="This ability's unique ID; matches the games' internal ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -121,9 +124,9 @@ create_translation_table('ability_names', Ability, 'names',
         info=dict(description="The name", format='plaintext', official=True, ripped=True)),
 )
 create_translation_table('ability_prose', Ability, 'prose',
         info=dict(description="The name", format='plaintext', official=True, ripped=True)),
 )
 create_translation_table('ability_prose', Ability, 'prose',
-    effect = Column(markdown.MarkdownColumn(5120), nullable=False,
+    effect = Column(markdown.MarkdownColumn(5120), nullable=True,
         info=dict(description="A detailed description of this ability's effect", format='markdown')),
         info=dict(description="A detailed description of this ability's effect", format='markdown')),
-    short_effect = Column(markdown.MarkdownColumn(255), nullable=False,
+    short_effect = Column(markdown.MarkdownColumn(512), nullable=True,
         info=dict(description="A short summary of this ability's effect", format='markdown')),
 )
 
         info=dict(description="A short summary of this ability's effect", format='markdown')),
 )
 
@@ -131,7 +134,7 @@ class AbilityChangelog(TableBase):
     """History of changes to abilities across main game versions."""
     __tablename__ = 'ability_changelog'
     __singlename__ = 'ability_changelog'
     """History of changes to abilities across main game versions."""
     __tablename__ = 'ability_changelog'
     __singlename__ = 'ability_changelog'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="This change's unique ID"))
     ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False,
         info=dict(description="The ID of the ability that changed"))
         info=dict(description="This change's unique ID"))
     ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False,
         info=dict(description="The ID of the ability that changed"))
@@ -151,7 +154,7 @@ class AbilityFlavorText(TableBase):
         info=dict(description="The ID of the ability"))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the version group this flavor text is taken from"))
         info=dict(description="The ID of the ability"))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the version group this flavor text is taken from"))
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False,
         info=dict(description="The language"))
     flavor_text = Column(Unicode(64), nullable=False,
         info=dict(description="The actual flavor text", official=True, format='gametext'))
         info=dict(description="The language"))
     flavor_text = Column(Unicode(64), nullable=False,
         info=dict(description="The actual flavor text", official=True, format='gametext'))
@@ -162,7 +165,7 @@ class Berry(TableBase):
     For data common to all items, such as the name, see the corresponding item entry.
     """
     __tablename__ = 'berries'
     For data common to all items, such as the name, see the corresponding item entry.
     """
     __tablename__ = 'berries'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="This Berry's in-game number"))
     item_id = Column(Integer, ForeignKey('items.id'), nullable=False,
         info=dict(description="The ID of the item that represents this Berry"))
         info=dict(description="This Berry's in-game number"))
     item_id = Column(Integer, ForeignKey('items.id'), nullable=False,
         info=dict(description="The ID of the item that represents this Berry"))
@@ -188,7 +191,7 @@ class BerryFirmness(TableBase):
     """
     __tablename__ = 'berry_firmness'
     __singlename__ = 'berry_firmness'
     """
     __tablename__ = 'berry_firmness'
     __singlename__ = 'berry_firmness'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this firmness"))
     identifier = Column(Unicode(10), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A unique ID for this firmness"))
     identifier = Column(Unicode(10), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -224,7 +227,7 @@ class ContestEffect(TableBase):
     """
     __tablename__ = 'contest_effects'
     __singlename__ = 'contest_effect'
     """
     __tablename__ = 'contest_effects'
     __singlename__ = 'contest_effect'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this effect"))
     appeal = Column(SmallInteger, nullable=False,
         info=dict(description="The base number of hearts the user of this move gets"))
         info=dict(description="A unique ID for this effect"))
     appeal = Column(SmallInteger, nullable=False,
         info=dict(description="The base number of hearts the user of this move gets"))
@@ -232,9 +235,9 @@ class ContestEffect(TableBase):
         info=dict(description="The base number of hearts the user's opponent loses"))
 
 create_translation_table('contest_effect_prose', ContestEffect, 'prose',
         info=dict(description="The base number of hearts the user's opponent loses"))
 
 create_translation_table('contest_effect_prose', ContestEffect, 'prose',
-    flavor_text = Column(Unicode(64), nullable=False,
+    flavor_text = Column(Unicode(64), nullable=True,
         info=dict(description="The in-game description of this effect", official=True, format='gametext')),
         info=dict(description="The in-game description of this effect", official=True, format='gametext')),
-    effect = Column(Unicode(255), nullable=False,
+    effect = Column(Unicode(255), nullable=True,
         info=dict(description="A detailed description of the effect", format='plaintext')),
 )
 
         info=dict(description="A detailed description of the effect", format='plaintext')),
 )
 
@@ -243,18 +246,18 @@ class ContestType(TableBase):
     """
     __tablename__ = 'contest_types'
     __singlename__ = 'contest_type'
     """
     __tablename__ = 'contest_types'
     __singlename__ = 'contest_type'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this Contest type"))
     identifier = Column(Unicode(6), nullable=False,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('contest_type_names', ContestType, 'names',
     relation_lazy='joined',
         info=dict(description="A unique ID for this Contest type"))
     identifier = Column(Unicode(6), nullable=False,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('contest_type_names', ContestType, 'names',
     relation_lazy='joined',
-    name = Column(Unicode(6), nullable=False, index=True,
+    name = Column(Unicode(6), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=True)),
         info=dict(description="The name", format='plaintext', official=True)),
-    flavor = Column(Unicode(6), nullable=False,
+    flavor = Column(Unicode(6), nullable=True,
         info=dict(description="The name of the corresponding Berry flavor", official=True, format='plaintext')),
         info=dict(description="The name of the corresponding Berry flavor", official=True, format='plaintext')),
-    color = Column(Unicode(6), nullable=False,
+    color = Column(Unicode(6), nullable=True,
         info=dict(description=u"The name of the corresponding Pokéblock color", official=True, format='plaintext')),
 )
 
         info=dict(description=u"The name of the corresponding Pokéblock color", official=True, format='plaintext')),
 )
 
@@ -265,7 +268,7 @@ class EggGroup(TableBase):
     """
     __tablename__ = 'egg_groups'
     __singlename__ = 'egg_group'
     """
     __tablename__ = 'egg_groups'
     __singlename__ = 'egg_group'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this group"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description=u"An identifier.", format='identifier'))
         info=dict(description="A unique ID for this group"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description=u"An identifier.", format='identifier'))
@@ -285,10 +288,10 @@ class Encounter(TableBase):
     "slot" they are in and the state of the game world.
 
     What the player is doing to get an encounter, such as surfing or walking
     "slot" they are in and the state of the game world.
 
     What the player is doing to get an encounter, such as surfing or walking
-    through tall grass, is called terrain.  Each terrain has its own set of
+    through tall grass, is called a method.  Each method has its own set of
     encounter slots.
 
     encounter slots.
 
-    Within a terrain, slots are defined primarily by rarity.  Each slot can
+    Within a method, slots are defined primarily by rarity.  Each slot can
     also be affected by world conditions; for example, the 20% slot for walking
     in tall grass is affected by whether a swarm is in effect in that area.
     "Is there a swarm?" is a condition; "there is a swarm" and "there is not a
     also be affected by world conditions; for example, the 20% slot for walking
     in tall grass is affected by whether a swarm is in effect in that area.
     "Is there a swarm?" is a condition; "there is a swarm" and "there is not a
@@ -301,14 +304,14 @@ class Encounter(TableBase):
     """
 
     __tablename__ = 'encounters'
     """
 
     __tablename__ = 'encounters'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this encounter"))
     version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False,
         info=dict(description="The ID of the version this applies to"))
     location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False,
         info=dict(description="The ID of the location of this encounter"))
     encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), nullable=False, autoincrement=False,
         info=dict(description="A unique ID for this encounter"))
     version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False,
         info=dict(description="The ID of the version this applies to"))
     location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False,
         info=dict(description="The ID of the location of this encounter"))
     encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), nullable=False, autoincrement=False,
-        info=dict(description="The ID of the encounter slot, which determines terrain and rarity"))
+        info=dict(description="The ID of the encounter slot, which determines method and rarity"))
     pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False,
         info=dict(description=u"The ID of the encountered Pokémon"))
     min_level = Column(Integer, nullable=False, autoincrement=False,
     pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False,
         info=dict(description=u"The ID of the encountered Pokémon"))
     min_level = Column(Integer, nullable=False, autoincrement=False,
@@ -322,7 +325,7 @@ class EncounterCondition(TableBase):
 
     __tablename__ = 'encounter_conditions'
     __singlename__ = 'encounter_condition'
 
     __tablename__ = 'encounter_conditions'
     __singlename__ = 'encounter_condition'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this condition"))
     identifier = Column(Unicode(64), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A unique ID for this condition"))
     identifier = Column(Unicode(64), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -338,7 +341,7 @@ class EncounterConditionValue(TableBase):
 
     __tablename__ = 'encounter_condition_values'
     __singlename__ = 'encounter_condition_value'
 
     __tablename__ = 'encounter_condition_values'
     __singlename__ = 'encounter_condition_value'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=False, nullable=False, autoincrement=False,
         info=dict(description="The ID of the encounter condition this is a value of"))
         info=dict(description="A numeric ID"))
     encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=False, nullable=False, autoincrement=False,
         info=dict(description="The ID of the encounter condition this is a value of"))
@@ -361,46 +364,46 @@ class EncounterConditionValueMap(TableBase):
     encounter_condition_value_id = Column(Integer, ForeignKey('encounter_condition_values.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the encounter condition value"))
 
     encounter_condition_value_id = Column(Integer, ForeignKey('encounter_condition_values.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The ID of the encounter condition value"))
 
+class EncounterMethod(TableBase):
+    u"""A way the player can enter a wild encounter, e.g., surfing, fishing, or walking through tall grass.
+    """
+
+    __tablename__ = 'encounter_methods'
+    __singlename__ = 'encounter_method'
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description="A unique ID for the method"))
+    identifier = Column(Unicode(16), nullable=False, unique=True,
+        info=dict(description="An identifier", format='identifier'))
+
+create_translation_table('encounter_method_prose', EncounterMethod, 'prose',
+    name = Column(Unicode(64), nullable=False, index=True,
+        info=dict(description="The name", format='plaintext', official=False)),
+)
+
 class EncounterSlot(TableBase):
 class EncounterSlot(TableBase):
-    u"""An abstract "slot" within a terrain, associated with both some set of conditions and a rarity.
+    u"""An abstract "slot" within a method, 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.
     """
 
     __tablename__ = 'encounter_slots'
 
     Note that there are two encounters per slot, so the rarities will only add
     up to 50.
     """
 
     __tablename__ = 'encounter_slots'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A unique ID for this slot"))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, autoincrement=False,
         info=dict(description="The ID of the version group this slot is in"))
         info=dict(description="A unique ID for this slot"))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, autoincrement=False,
         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"))
+    encounter_method_id = Column(Integer, ForeignKey('encounter_methods.id'), primary_key=False, nullable=False, autoincrement=False,
+        info=dict(description="The ID of the method"))
     slot = Column(Integer, nullable=True,
     slot = Column(Integer, nullable=True,
-        info=dict(description="This slot's order for the location and terrain"))
-    rarity = Column(Integer, nullable=False,
+        info=dict(description="This slot's order for the location and method"))
+    rarity = Column(Integer, nullable=True,
         info=dict(description="The chance of the encounter as a percentage"))
 
         info=dict(description="The chance of the encounter as a percentage"))
 
-class EncounterTerrain(TableBase):
-    u"""A way the player can enter a wild encounter, e.g., surfing, fishing, or walking through tall grass.
-    """
-
-    __tablename__ = 'encounter_terrain'
-    __singlename__ = __tablename__
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
-        info=dict(description="A unique ID for the terrain"))
-    identifier = Column(Unicode(64), nullable=False,
-        info=dict(description="An identifier", format='identifier'))
-
-create_translation_table('encounter_terrain_prose', EncounterTerrain, 'prose',
-    name = Column(Unicode(64), nullable=False, index=True,
-        info=dict(description="The name", format='plaintext', official=False)),
-)
-
 class EvolutionChain(TableBase):
     u"""A family of Pokémon that are linked by evolution
     """
     __tablename__ = 'evolution_chains'
 class EvolutionChain(TableBase):
     u"""A family of Pokémon that are linked by evolution
     """
     __tablename__ = 'evolution_chains'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), nullable=False,
         info=dict(description="ID of the growth rate for this family"))
         info=dict(description="A numeric ID"))
     growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), nullable=False,
         info=dict(description="ID of the growth rate for this family"))
@@ -412,7 +415,7 @@ class EvolutionTrigger(TableBase):
     """
     __tablename__ = 'evolution_triggers'
     __singlename__ = 'evolution_trigger'
     """
     __tablename__ = 'evolution_triggers'
     __singlename__ = 'evolution_trigger'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -426,7 +429,7 @@ class Experience(TableBase):
     u"""EXP needed for a certain level with a certain growth rate
     """
     __tablename__ = 'experience'
     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, autoincrement=False,
+    growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), primary_key=True, nullable=False,
         info=dict(description="ID of the growth rate"))
     level = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The level"))
         info=dict(description="ID of the growth rate"))
     level = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="The level"))
@@ -438,7 +441,7 @@ class Generation(TableBase):
     """
     __tablename__ = 'generations'
     __singlename__ = 'generation'
     """
     __tablename__ = 'generations'
     __singlename__ = 'generation'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     main_region_id = Column(Integer, ForeignKey('regions.id'), nullable=False,
         info=dict(description="ID of the region this generation's main games take place in"))
         info=dict(description="A numeric ID"))
     main_region_id = Column(Integer, ForeignKey('regions.id'), nullable=False,
         info=dict(description="ID of the region this generation's main games take place in"))
@@ -458,7 +461,7 @@ class GrowthRate(TableBase):
     """
     __tablename__ = 'growth_rates'
     __singlename__ = 'growth_rate'
     """
     __tablename__ = 'growth_rates'
     __singlename__ = 'growth_rate'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(20), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(20), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -475,7 +478,7 @@ class Item(TableBase):
     """
     __tablename__ = 'items'
     __singlename__ = 'item'
     """
     __tablename__ = 'items'
     __singlename__ = 'item'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(20), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(20), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -500,9 +503,9 @@ create_translation_table('item_names', Item, 'names',
         info=dict(description="The name", format='plaintext', official=True, ripped=True)),
 )
 create_translation_table('item_prose', Item, 'prose',
         info=dict(description="The name", format='plaintext', official=True, ripped=True)),
 )
 create_translation_table('item_prose', Item, 'prose',
-    short_effect = Column(markdown.MarkdownColumn(256), nullable=False,
-        info=dict(description="A short summary of the effect", format='plaintext')),
-    effect = Column(markdown.MarkdownColumn(5120), nullable=False,
+    short_effect = Column(markdown.MarkdownColumn(256), nullable=True,
+        info=dict(description="A short summary of the effect", format='markdown')),
+    effect = Column(markdown.MarkdownColumn(5120), nullable=True,
         info=dict(description=u"Detailed description of the item's effect.", format='markdown')),
 )
 create_translation_table('item_flavor_summaries', Item, 'flavor_summaries',
         info=dict(description=u"Detailed description of the item's effect.", format='markdown')),
 )
 create_translation_table('item_flavor_summaries', Item, 'flavor_summaries',
@@ -516,7 +519,7 @@ class ItemCategory(TableBase):
     # XXX: This is fanon, right?
     __tablename__ = 'item_categories'
     __singlename__ = 'item_category'
     # XXX: This is fanon, right?
     __tablename__ = 'item_categories'
     __singlename__ = 'item_category'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     pocket_id = Column(Integer, ForeignKey('item_pockets.id'), nullable=False,
         info=dict(description="ID of the pocket these items go to"))
         info=dict(description="A numeric ID"))
     pocket_id = Column(Integer, ForeignKey('item_pockets.id'), nullable=False,
         info=dict(description="ID of the pocket these items go to"))
@@ -534,15 +537,15 @@ class ItemFlag(TableBase):
     """
     __tablename__ = 'item_flags'
     __singlename__ = 'item_flag'
     """
     __tablename__ = 'item_flags'
     __singlename__ = 'item_flag'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description="Identifier of the flag", format='identifier'))
 
 create_translation_table('item_flag_prose', ItemFlag, 'prose',
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description="Identifier of the flag", format='identifier'))
 
 create_translation_table('item_flag_prose', ItemFlag, 'prose',
-    name = Column(Unicode(24), nullable=False, index=True,
+    name = Column(Unicode(24), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    description = Column(Unicode(64), nullable=False,
+    description = Column(Unicode(64), nullable=True,
         info=dict(description="Short description of the flag", format='plaintext')),
 )
 
         info=dict(description="Short description of the flag", format='plaintext')),
 )
 
@@ -565,7 +568,7 @@ class ItemFlavorText(TableBase):
         info=dict(description="The ID of the item"))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="ID of the version group that sports this text"))
         info=dict(description="The ID of the item"))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, autoincrement=False, nullable=False,
         info=dict(description="ID of the version group that sports this text"))
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False,
         info=dict(description="The language"))
     flavor_text = Column(Unicode(255), nullable=False,
         info=dict(description="The flavor text itself", official=True, format='gametext'))
         info=dict(description="The language"))
     flavor_text = Column(Unicode(255), nullable=False,
         info=dict(description="The flavor text itself", official=True, format='gametext'))
@@ -575,7 +578,7 @@ class ItemFlingEffect(TableBase):
     """
     __tablename__ = 'item_fling_effects'
     __singlename__ = 'item_fling_effect'
     """
     __tablename__ = 'item_fling_effects'
     __singlename__ = 'item_fling_effect'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
 
 create_translation_table('item_fling_effect_prose', ItemFlingEffect, 'prose',
         info=dict(description="A numeric ID"))
 
 create_translation_table('item_fling_effect_prose', ItemFlingEffect, 'prose',
@@ -599,7 +602,7 @@ class ItemPocket(TableBase):
     """
     __tablename__ = 'item_pockets'
     __singlename__ = 'item_pocket'
     """
     __tablename__ = 'item_pockets'
     __singlename__ = 'item_pocket'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description="An identifier of this pocket", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description="An identifier of this pocket", format='identifier'))
@@ -615,7 +618,7 @@ class Location(TableBase):
     """
     __tablename__ = 'locations'
     __singlename__ = 'location'
     """
     __tablename__ = 'locations'
     __singlename__ = 'location'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=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"))
         info=dict(description="A numeric ID"))
     region_id = Column(Integer, ForeignKey('regions.id'),
         info=dict(description="ID of the region this location is in"))
@@ -633,7 +636,7 @@ class LocationArea(TableBase):
     """
     __tablename__ = 'location_areas'
     __singlename__ = 'location_area'
     """
     __tablename__ = 'location_areas'
     __singlename__ = 'location_area'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    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"))
         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"))
@@ -653,8 +656,8 @@ class LocationAreaEncounterRate(TableBase):
     __tablename__ = 'location_area_encounter_rates'
     location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="ID of the area"))
     __tablename__ = 'location_area_encounter_rates'
     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"))
+    encounter_method_id = Column(Integer, ForeignKey('encounter_methods.id'), primary_key=True, nullable=False, autoincrement=False,
+        info=dict(description="ID of the method"))
     version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, autoincrement=False,
         info=dict(description="ID of the version"))
     rate = Column(Integer, nullable=True,
     version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, autoincrement=False,
         info=dict(description="ID of the version"))
     rate = Column(Integer, nullable=True,
@@ -664,11 +667,11 @@ class LocationGameIndex(TableBase):
     u"""IDs the games use internally for locations
     """
     __tablename__ = 'location_game_indices'
     u"""IDs the games use internally for locations
     """
     __tablename__ = 'location_game_indices'
-    location_id = Column(Integer, ForeignKey('locations.id'), nullable=False, primary_key=True, autoincrement=False,
+    location_id = Column(Integer, ForeignKey('locations.id'), nullable=False, primary_key=True,
         info=dict(description="Database ID of the locaion"))
         info=dict(description="Database ID of the locaion"))
-    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False, primary_key=True, autoincrement=False,
+    generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False, primary_key=True,
         info=dict(description="ID of the generation this entry to"))
         info=dict(description="ID of the generation this entry to"))
-    game_index = Column(Integer, nullable=False,
+    game_index = Column(Integer, nullable=False, primary_key=True, autoincrement=False,
         info=dict(description="Internal game ID of the location"))
 
 class Machine(TableBase):
         info=dict(description="Internal game ID of the location"))
 
 class Machine(TableBase):
@@ -695,7 +698,7 @@ class Move(TableBase):
     """
     __tablename__ = 'moves'
     __singlename__ = 'move'
     """
     __tablename__ = 'moves'
     __singlename__ = 'move'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -740,7 +743,7 @@ class MoveBattleStyle(TableBase):
     u"""A battle style of a move"""  # XXX: Explain better
     __tablename__ = 'move_battle_styles'
     __singlename__ = 'move_battle_style'
     u"""A battle style of a move"""  # XXX: Explain better
     __tablename__ = 'move_battle_styles'
     __singlename__ = 'move_battle_style'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(8), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(8), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -755,9 +758,9 @@ class MoveChangelog(TableBase):
     """History of changes to moves across main game versions."""
     __tablename__ = 'move_changelog'
     __singlename__ = 'move_changelog'
     """History of changes to moves across main game versions."""
     __tablename__ = 'move_changelog'
     __singlename__ = 'move_changelog'
-    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False,
+    move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False,
         info=dict(description="ID of the move that changed"))
         info=dict(description="ID of the move that changed"))
-    changed_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
+    changed_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False,
         info=dict(description="ID of the version group in which the move changed"))
     type_id = Column(Integer, ForeignKey('types.id'), nullable=True,
         info=dict(description="Prior type of the move, or NULL if unchanged"))
         info=dict(description="ID of the version group in which the move changed"))
     type_id = Column(Integer, ForeignKey('types.id'), nullable=True,
         info=dict(description="Prior type of the move, or NULL if unchanged"))
@@ -777,16 +780,16 @@ class MoveDamageClass(TableBase):
     """
     __tablename__ = 'move_damage_classes'
     __singlename__ = 'move_damage_class'
     """
     __tablename__ = 'move_damage_classes'
     __singlename__ = 'move_damage_class'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_damage_class_prose', MoveDamageClass, 'prose',
     relation_lazy='joined',
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_damage_class_prose', MoveDamageClass, 'prose',
     relation_lazy='joined',
-    name = Column(Unicode(16), nullable=False, index=True,
+    name = Column(Unicode(16), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    description = Column(Unicode(64), nullable=False,
+    description = Column(Unicode(64), nullable=True,
         info=dict(description="A description of the class", format='plaintext')),
 )
 
         info=dict(description="A description of the class", format='plaintext')),
 )
 
@@ -795,49 +798,21 @@ class MoveEffect(TableBase):
     """
     __tablename__ = 'move_effects'
     __singlename__ = 'move_effect'
     """
     __tablename__ = 'move_effects'
     __singlename__ = 'move_effect'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
 
 create_translation_table('move_effect_prose', MoveEffect, 'prose',
         info=dict(description="A numeric ID"))
 
 create_translation_table('move_effect_prose', MoveEffect, 'prose',
-    short_effect = Column(Unicode(256), nullable=False,
+    short_effect = Column(Unicode(256), nullable=True,
         info=dict(description="A short summary of the effect", format='plaintext')),
         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 MoveEffectCategory(TableBase):
-    u"""Category of a move effect
-    """
-    __tablename__ = 'move_effect_categories'
-    __singlename__ = 'move_effect_category'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
-        info=dict(description="A numeric ID"))
-    identifier = Column(Unicode(64), nullable=False,
-        info=dict(description="An identifier", format='identifier'))
-    can_affect_user = Column(Boolean, nullable=False,
-        info=dict(description="Set if the user can be affected"))
-
-create_translation_table('move_effect_category_prose', MoveEffectCategory, 'prose',
-    name = Column(Unicode(64), nullable=False, index=True,
-        info=dict(description="The name", format='plaintext', official=False)),
+    effect = Column(Unicode(5120), nullable=True,
+        info=dict(description="A detailed description of the effect", format='markdown')),
 )
 
 )
 
-class MoveEffectCategoryMap(TableBase):
-    u"""Maps a move effect category to a move effect
-    """
-    __tablename__ = 'move_effect_category_map'
-    move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False, autoincrement=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, autoincrement=False,
-        info=dict(description="ID of the category"))
-    affects_user = Column(Boolean, primary_key=True, nullable=False, autoincrement=False,
-        info=dict(description="Set if the user is affected"))
-
 class MoveEffectChangelog(TableBase):
     """History of changes to move effects across main game versions."""
     __tablename__ = 'move_effect_changelog'
     __singlename__ = 'move_effect_changelog'
 class MoveEffectChangelog(TableBase):
     """History of changes to move effects across main game versions."""
     __tablename__ = 'move_effect_changelog'
     __singlename__ = 'move_effect_changelog'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False,
         info=dict(description="The ID of the effect that changed"))
         info=dict(description="A numeric ID"))
     effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False,
         info=dict(description="The ID of the effect that changed"))
@@ -870,16 +845,16 @@ class MoveFlagType(TableBase):
     """
     __tablename__ = 'move_flag_types'
     __singlename__ = 'move_flag_type'
     """
     __tablename__ = 'move_flag_types'
     __singlename__ = 'move_flag_type'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(32), nullable=False,
         info=dict(description="A short identifier for the flag", format='identifier'))
 
 create_translation_table('move_flag_type_prose', MoveFlagType, 'prose',
     relation_lazy='joined',
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(32), nullable=False,
         info=dict(description="A short identifier for the flag", format='identifier'))
 
 create_translation_table('move_flag_type_prose', MoveFlagType, 'prose',
     relation_lazy='joined',
-    name = Column(Unicode(32), nullable=False, index=True,
+    name = Column(Unicode(32), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    description = Column(markdown.MarkdownColumn(128), nullable=False,
+    description = Column(markdown.MarkdownColumn(256), nullable=True,
         info=dict(description="A short description of the flag", format='markdown')),
 )
 
         info=dict(description="A short description of the flag", format='markdown')),
 )
 
@@ -892,7 +867,7 @@ class MoveFlavorText(TableBase):
         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"))
         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"))
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False,
         info=dict(description="The language"))
     flavor_text = Column(Unicode(255), nullable=False,
         info=dict(description="The flavor text", official=True, format='gametext'))
         info=dict(description="The language"))
     flavor_text = Column(Unicode(255), nullable=False,
         info=dict(description="The flavor text", official=True, format='gametext'))
@@ -935,7 +910,7 @@ class MoveMetaAilment(TableBase):
     __singlename__ = 'move_meta_ailment'
     id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="A numeric ID"))
     __singlename__ = 'move_meta_ailment'
     id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
         info=dict(description="A numeric ID"))
-    identifier = Column(Unicode(24), nullable=False,
+    identifier = Column(Unicode(24), nullable=False, index=True, unique=True,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_meta_ailment_names', MoveMetaAilment, 'names',
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_meta_ailment_names', MoveMetaAilment, 'names',
@@ -948,8 +923,10 @@ class MoveMetaCategory(TableBase):
     u"""Very general categories that loosely group move effects."""
     __tablename__ = 'move_meta_categories'
     __singlename__ = 'move_meta_category'
     u"""Very general categories that loosely group move effects."""
     __tablename__ = 'move_meta_categories'
     __singlename__ = 'move_meta_category'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
         info=dict(description="A numeric ID"))
+    identifier = Column(Unicode(32), nullable=False, index=True, unique=True,
+        info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_meta_category_prose', MoveMetaCategory, 'prose',
     relation_lazy='joined',
 
 create_translation_table('move_meta_category_prose', MoveMetaCategory, 'prose',
     relation_lazy='joined',
@@ -972,16 +949,16 @@ class MoveTarget(TableBase):
     """
     __tablename__ = 'move_targets'
     __singlename__ = 'move_target'
     """
     __tablename__ = 'move_targets'
     __singlename__ = 'move_target'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(32), nullable=False,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_target_prose', MoveTarget, 'prose',
     relation_lazy='joined',
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(32), nullable=False,
         info=dict(description="An identifier", format='identifier'))
 
 create_translation_table('move_target_prose', MoveTarget, 'prose',
     relation_lazy='joined',
-    name = Column(Unicode(32), nullable=False, index=True,
+    name = Column(Unicode(32), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    description = Column(Unicode(128), nullable=False,
+    description = Column(Unicode(128), nullable=True,
         info=dict(description="A description", format='plaintext')),
 )
 
         info=dict(description="A description", format='plaintext')),
 )
 
@@ -990,7 +967,7 @@ class Nature(TableBase):
     """
     __tablename__ = 'natures'
     __singlename__ = 'nature'
     """
     __tablename__ = 'natures'
     __singlename__ = 'nature'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(8), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(8), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -1023,9 +1000,9 @@ class NatureBattleStylePreference(TableBase):
     a particular battl style in Battle Palace or Battle Tent
     """
     __tablename__ = 'nature_battle_style_preferences'
     a particular battl style in Battle Palace or Battle Tent
     """
     __tablename__ = 'nature_battle_style_preferences'
-    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False, autoincrement=False,
+    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False,
         info=dict(description=u"ID of the Pokémon's nature"))
         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, autoincrement=False,
+    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 ½"))
         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 ½"))
@@ -1036,9 +1013,9 @@ class NaturePokeathlonStat(TableBase):
     u"""Specifies how a Nature affects a Pokéathlon stat
     """
     __tablename__ = 'nature_pokeathlon_stats'
     u"""Specifies how a Nature affects a Pokéathlon stat
     """
     __tablename__ = 'nature_pokeathlon_stats'
-    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False, autoincrement=False,
+    nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False,
         info=dict(description="ID of the nature"))
         info=dict(description="ID of the nature"))
-    pokeathlon_stat_id = Column(Integer, ForeignKey('pokeathlon_stats.id'), primary_key=True, nullable=False, autoincrement=False,
+    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"))
         info=dict(description="ID of the stat"))
     max_change = Column(Integer, nullable=False,
         info=dict(description="Maximum change"))
@@ -1048,7 +1025,7 @@ class PokeathlonStat(TableBase):
     """
     __tablename__ = 'pokeathlon_stats'
     __singlename__ = 'pokeathlon_stat'
     """
     __tablename__ = 'pokeathlon_stats'
     __singlename__ = 'pokeathlon_stat'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(8), nullable=False,
         info=dict(description="An identifier", format='identifier'))
         info=dict(description="A numeric ID"))
     identifier = Column(Unicode(8), nullable=False,
         info=dict(description="An identifier", format='identifier'))
@@ -1063,7 +1040,7 @@ class Pokedex(TableBase):
     """
     __tablename__ = 'pokedexes'
     __singlename__ = 'pokedex'
     """
     __tablename__ = 'pokedexes'
     __singlename__ = 'pokedex'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    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"))
         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"))
@@ -1072,9 +1049,9 @@ class Pokedex(TableBase):
 
 create_translation_table('pokedex_prose', Pokedex, 'prose',
     relation_lazy='joined',
 
 create_translation_table('pokedex_prose', Pokedex, 'prose',
     relation_lazy='joined',
-    name = Column(Unicode(16), nullable=False, index=True,
+    name = Column(Unicode(16), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    description = Column(Unicode(512), nullable=False,
+    description = Column(Unicode(512), nullable=True,
         info=dict(description=u"A longer description of the Pokédex", format='plaintext')),
 )
 
         info=dict(description=u"A longer description of the Pokédex", format='plaintext')),
 )
 
@@ -1083,7 +1060,7 @@ class Pokemon(TableBase):
     """
     __tablename__ = 'pokemon'
     __singlename__ = 'pokemon'
     """
     __tablename__ = 'pokemon'
     __singlename__ = 'pokemon'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"A numeric ID"))
     identifier = Column(Unicode(20), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
         info=dict(description=u"A numeric ID"))
     identifier = Column(Unicode(20), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
@@ -1091,6 +1068,8 @@ class Pokemon(TableBase):
         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)"))
         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)"))
+    evolves_from_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=True,
+        info=dict(description=u"The Pokémon species from which this one evolves"))
     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,
     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,
@@ -1121,12 +1100,6 @@ class Pokemon(TableBase):
     ### Stuff to handle alternate Pokémon forms
 
     @property
     ### Stuff to handle alternate Pokémon forms
 
     @property
-    def form(self):
-        u"""Returns the Pokémon's form, using its default form as fallback."""
-
-        return self.unique_form or self.default_form
-
-    @property
     def is_base_form(self):
         u"""Returns True iff the Pokémon is the base form for its species,
         e.g. Land Shaymin.
     def is_base_form(self):
         u"""Returns True iff the Pokémon is the base form for its species,
         e.g. Land Shaymin.
@@ -1150,7 +1123,7 @@ class Pokemon(TableBase):
         u"""Returns the Pokémon's name, including its form if applicable."""
 
         if self.form_name:
         u"""Returns the Pokémon's name, including its form if applicable."""
 
         if self.form_name:
-            return u'{0} {1}'.format(self.form_name, self.name)
+            return u'%s %s' % (self.form_name, self.name)
         else:
             return self.name
 
         else:
             return self.name
 
@@ -1202,9 +1175,9 @@ class Pokemon(TableBase):
 
 create_translation_table('pokemon_names', Pokemon, 'names',
     relation_lazy='joined',
 
 create_translation_table('pokemon_names', Pokemon, 'names',
     relation_lazy='joined',
-    name = Column(Unicode(20), nullable=False, index=True,
+    name = Column(Unicode(20), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=True, ripped=True)),
         info=dict(description="The name", format='plaintext', official=True, ripped=True)),
-    species = Column(Unicode(16), nullable=False,
+    species = Column(Unicode(16), nullable=True,
         info=dict(description=u'The short flavor text, such as "Seed" or "Lizard"; usually affixed with the word "Pokémon"',
         official=True, format='plaintext')),
 )
         info=dict(description=u'The short flavor text, such as "Seed" or "Lizard"; usually affixed with the word "Pokémon"',
         official=True, format='plaintext')),
 )
@@ -1272,9 +1245,9 @@ class PokemonEvolution(TableBase):
     Any condition may be null if it does not apply for a particular Pokémon.
     """
     __tablename__ = 'pokemon_evolution'
     Any condition may be null if it does not apply for a particular Pokémon.
     """
     __tablename__ = 'pokemon_evolution'
-    from_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False,
-        info=dict(description=u"The ID of the pre-evolution Pokémon."))
-    to_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
+        info=dict(description=u"A numeric ID"))
+    evolved_pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False,
         info=dict(description=u"The ID of the post-evolution Pokémon."))
     evolution_trigger_id = Column(Integer, ForeignKey('evolution_triggers.id'), nullable=False,
         info=dict(description=u"The ID of the evolution trigger."))
         info=dict(description=u"The ID of the post-evolution Pokémon."))
     evolution_trigger_id = Column(Integer, ForeignKey('evolution_triggers.id'), nullable=False,
         info=dict(description=u"The ID of the evolution trigger."))
@@ -1312,7 +1285,7 @@ class PokemonFlavorText(TableBase):
         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"))
         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"))
-    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False,
+    language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False,
         info=dict(description="The language"))
     flavor_text = Column(Unicode(255), nullable=False,
         info=dict(description=u"The flavor text", official=True, format='gametext'))
         info=dict(description="The language"))
     flavor_text = Column(Unicode(255), nullable=False,
         info=dict(description=u"The flavor text", official=True, format='gametext'))
@@ -1325,7 +1298,7 @@ class PokemonForm(TableBase):
     """
     __tablename__ = 'pokemon_forms'
     __singlename__ = 'pokemon_form'
     """
     __tablename__ = 'pokemon_forms'
     __singlename__ = 'pokemon_form'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u'A unique ID for this form.'))
     identifier = Column(Unicode(16), nullable=True,
         info=dict(description=u"An identifier", format='identifier'))
         info=dict(description=u'A unique ID for this form.'))
     identifier = Column(Unicode(16), nullable=True,
         info=dict(description=u"An identifier", format='identifier'))
@@ -1341,20 +1314,13 @@ class PokemonForm(TableBase):
         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
         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 pokemon(self):
-        u"""Returns the Pokémon for this form, using the form base as fallback.
-        """
-
-        return self.unique_pokemon or self.form_base_pokemon
-
-    @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:
     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 u'{0} {1}'.format(self.name, self.form_group.term)
+            return u'%s %s' % (self.name, self.form_group.term)
         else:
             return self.name
 
         else:
             return self.name
 
@@ -1365,7 +1331,7 @@ class PokemonForm(TableBase):
         """
 
         if self.name:
         """
 
         if self.name:
-            return u'{0} {1}'.format(self.name, self.form_base_pokemon.name)
+            return u'%s %s' % (self.name, self.form_base_pokemon.name)
         else:
             return self.form_base_pokemon.name
 
         else:
             return self.form_base_pokemon.name
 
@@ -1389,7 +1355,7 @@ PokemonFormGroup.id = PokemonFormGroup.pokemon_id
 create_translation_table('pokemon_form_group_prose', PokemonFormGroup, 'prose',
     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')),
 create_translation_table('pokemon_form_group_prose', PokemonFormGroup, 'prose',
     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')),
-    description = Column(markdown.MarkdownColumn(1024), nullable=False,
+    description = Column(markdown.MarkdownColumn(1024), nullable=True,
         info=dict(description=u"Description of how the forms work", format='markdown')),
 )
 
         info=dict(description=u"Description of how the forms work", format='markdown')),
 )
 
@@ -1481,9 +1447,9 @@ class PokemonMoveMethod(TableBase):
 
 create_translation_table('pokemon_move_method_prose', PokemonMoveMethod, 'prose',
     relation_lazy='joined',
 
 create_translation_table('pokemon_move_method_prose', PokemonMoveMethod, 'prose',
     relation_lazy='joined',
-    name = Column(Unicode(64), nullable=False, index=True,
+    name = Column(Unicode(64), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    description = Column(Unicode(255), nullable=False,
+    description = Column(Unicode(255), nullable=True,
         info=dict(description=u"A detailed description of how the method works", format='plaintext')),
 )
 
         info=dict(description=u"A detailed description of how the method works", format='plaintext')),
 )
 
@@ -1492,16 +1458,16 @@ class PokemonShape(TableBase):
     """
     __tablename__ = 'pokemon_shapes'
     __singlename__ = 'pokemon_shape'
     """
     __tablename__ = 'pokemon_shapes'
     __singlename__ = 'pokemon_shape'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"A numeric ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
 
 create_translation_table('pokemon_shape_prose', PokemonShape, 'prose',
     relation_lazy='joined',
         info=dict(description=u"A numeric ID"))
     identifier = Column(Unicode(24), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
 
 create_translation_table('pokemon_shape_prose', PokemonShape, 'prose',
     relation_lazy='joined',
-    name = Column(Unicode(24), nullable=False, index=True,
+    name = Column(Unicode(24), nullable=True, index=True,
         info=dict(description="The name", format='plaintext', official=False)),
         info=dict(description="The name", format='plaintext', official=False)),
-    awesome_name = Column(Unicode(16), nullable=False,
+    awesome_name = Column(Unicode(16), nullable=True,
         info=dict(description=u"A splendiferous name of the body shape", format='plaintext')),
 )
 
         info=dict(description=u"A splendiferous name of the body shape", format='plaintext')),
 )
 
@@ -1534,7 +1500,7 @@ class Region(TableBase):
     """
     __tablename__ = 'regions'
     __singlename__ = 'region'
     """
     __tablename__ = 'regions'
     __singlename__ = 'region'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
         info=dict(description=u"A numeric ID"))
     identifier = Column(Unicode(16), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
@@ -1550,7 +1516,7 @@ class Stat(TableBase):
     """
     __tablename__ = 'stats'
     __singlename__ = 'stat'
     """
     __tablename__ = 'stats'
     __singlename__ = 'stat'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=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)"))
         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)"))
@@ -1571,7 +1537,7 @@ class StatHint(TableBase):
     """
     __tablename__ = 'stat_hints'
     __singlename__ = 'stat_hint'
     """
     __tablename__ = 'stat_hints'
     __singlename__ = 'stat_hint'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"A numeric ID"))
     stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False,
         info=dict(description=u"ID of the highest stat"))
         info=dict(description=u"A numeric ID"))
     stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False,
         info=dict(description=u"ID of the highest stat"))
@@ -1598,7 +1564,7 @@ class SuperContestEffect(TableBase):
     """
     __tablename__ = 'super_contest_effects'
     __singlename__ = 'super_contest_effect'
     """
     __tablename__ = 'super_contest_effects'
     __singlename__ = 'super_contest_effect'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"This effect's unique ID."))
     appeal = Column(SmallInteger, nullable=False,
         info=dict(description=u"The number of hearts the user gains."))
         info=dict(description=u"This effect's unique ID."))
     appeal = Column(SmallInteger, nullable=False,
         info=dict(description=u"The number of hearts the user gains."))
@@ -1612,7 +1578,7 @@ class Type(TableBase):
     u"""Any of the elemental types Pokémon and moves can have."""
     __tablename__ = 'types'
     __singlename__ = 'type'
     u"""Any of the elemental types Pokémon and moves can have."""
     __tablename__ = 'types'
     __singlename__ = 'type'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"A unique ID for this type."))
     identifier = Column(Unicode(12), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
         info=dict(description=u"A unique ID for this type."))
     identifier = Column(Unicode(12), nullable=False,
         info=dict(description=u"An identifier", format='identifier'))
@@ -1643,7 +1609,7 @@ class Version(TableBase):
     u"""An individual main-series Pokémon game."""
     __tablename__ = 'versions'
     __singlename__ = 'version'
     u"""An individual main-series Pokémon game."""
     __tablename__ = 'versions'
     __singlename__ = 'version'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"A unique ID for this version."))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False,
         info=dict(description=u"The ID of the version group this game belongs to."))
         info=dict(description=u"A unique ID for this version."))
     version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False,
         info=dict(description=u"The ID of the version group this game belongs to."))
@@ -1661,7 +1627,7 @@ class VersionGroup(TableBase):
     and Blue) or a single game (such as Yellow.)
     """
     __tablename__ = 'version_groups'
     and Blue) or a single game (such as Yellow.)
     """
     __tablename__ = 'version_groups'
-    id = Column(Integer, primary_key=True, nullable=False, autoincrement=False,
+    id = Column(Integer, primary_key=True, nullable=False,
         info=dict(description=u"This version group's unique ID."))
     generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False,
         info=dict(description=u"The ID of the generation the games in this group belong to."))
         info=dict(description=u"This version group's unique ID."))
     generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False,
         info=dict(description=u"The ID of the generation the games in this group belong to."))
@@ -1671,9 +1637,9 @@ class VersionGroup(TableBase):
 class VersionGroupRegion(TableBase):
     u"""Maps a version group to a region that appears in it."""
     __tablename__ = 'version_group_regions'
 class VersionGroupRegion(TableBase):
     u"""Maps a version group to a region that appears in it."""
     __tablename__ = 'version_group_regions'
-    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False,
+    version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False,
         info=dict(description=u"The ID of the version group."))
         info=dict(description=u"The ID of the version group."))
-    region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False, autoincrement=False,
+    region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False,
         info=dict(description=u"The ID of the region."))
 
 
         info=dict(description=u"The ID of the region."))
 
 
@@ -1744,7 +1710,7 @@ EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
     innerjoin=True, lazy='joined',
     backref='encounter_map')
 
     innerjoin=True, lazy='joined',
     backref='encounter_map')
 
-EncounterSlot.terrain = relation(EncounterTerrain,
+EncounterSlot.method = relation(EncounterMethod,
     innerjoin=True, lazy='joined',
     backref='slots')
 EncounterSlot.version_group = relation(VersionGroup, innerjoin=True)
     innerjoin=True, lazy='joined',
     backref='slots')
 EncounterSlot.version_group = relation(VersionGroup, innerjoin=True)
@@ -1821,6 +1787,12 @@ LocationArea.location = relation(Location,
     innerjoin=True, lazy='joined',
     backref='areas')
 
     innerjoin=True, lazy='joined',
     backref='areas')
 
+LocationAreaEncounterRate.location_area = relation(LocationArea,
+    innerjoin=True,
+    backref='encounter_rates')
+LocationAreaEncounterRate.method = relation(EncounterMethod,
+    innerjoin=True)
+
 LocationGameIndex.location = relation(Location,
     innerjoin=True, lazy='joined',
     backref='game_indices')
 LocationGameIndex.location = relation(Location,
     innerjoin=True, lazy='joined',
     backref='game_indices')
@@ -1891,12 +1863,9 @@ MoveChangelog.effect_map = markdown.MoveEffectPropertyMap('effect_map')
 MoveChangelog.short_effect = markdown.MoveEffectProperty('short_effect')
 MoveChangelog.short_effect_map = markdown.MoveEffectPropertyMap('short_effect_map')
 
 MoveChangelog.short_effect = markdown.MoveEffectProperty('short_effect')
 MoveChangelog.short_effect_map = markdown.MoveEffectPropertyMap('short_effect_map')
 
-MoveEffect.category_map = relation(MoveEffectCategoryMap)
-MoveEffect.categories = association_proxy('category_map', 'category')
 MoveEffect.changelog = relation(MoveEffectChangelog,
     order_by=MoveEffectChangelog.changed_in_version_group_id.desc(),
     backref='move_effect')
 MoveEffect.changelog = relation(MoveEffectChangelog,
     order_by=MoveEffectChangelog.changed_in_version_group_id.desc(),
     backref='move_effect')
-MoveEffectCategoryMap.category = relation(MoveEffectCategory)
 
 MoveEffectChangelog.changed_in = relation(VersionGroup,
     innerjoin=True, lazy='joined',
 
 MoveEffectChangelog.changed_in = relation(VersionGroup,
     innerjoin=True, lazy='joined',
@@ -2008,11 +1977,13 @@ Pokemon.egg_groups = relation(EggGroup,
 Pokemon.evolution_chain = relation(EvolutionChain,
     innerjoin=True,
     backref=backref('pokemon', order_by=Pokemon.order.asc()))
 Pokemon.evolution_chain = relation(EvolutionChain,
     innerjoin=True,
     backref=backref('pokemon', order_by=Pokemon.order.asc()))
-Pokemon.child_pokemon = relation(Pokemon,
-    primaryjoin=Pokemon.id==PokemonEvolution.from_pokemon_id,
-    secondary=PokemonEvolution.__table__,
-    secondaryjoin=PokemonEvolution.to_pokemon_id==Pokemon.id,
-    backref=backref('parent_pokemon', uselist=False))
+Pokemon.parent_pokemon = relation(Pokemon,
+    primaryjoin=Pokemon.evolves_from_pokemon_id==Pokemon.id,
+    remote_side=[Pokemon.id],
+    backref='child_pokemon')
+Pokemon.evolutions = relation(PokemonEvolution,
+    primaryjoin=Pokemon.id==PokemonEvolution.evolved_pokemon_id,
+    backref=backref('evolved_pokemon', innerjoin=True, lazy='joined'))
 Pokemon.flavor_text = relation(PokemonFlavorText,
     order_by=PokemonFlavorText.version_id.asc(),
     backref='pokemon')
 Pokemon.flavor_text = relation(PokemonFlavorText,
     order_by=PokemonFlavorText.version_id.asc(),
     backref='pokemon')
@@ -2044,24 +2015,18 @@ Pokemon.types = relation(Type,
     innerjoin=True,
     order_by=PokemonType.slot.asc(),
     backref=backref('pokemon', order_by=Pokemon.order))
     innerjoin=True,
     order_by=PokemonType.slot.asc(),
     backref=backref('pokemon', order_by=Pokemon.order))
+Pokemon.form = relation(PokemonForm,
+    primaryjoin=or_(
+        PokemonForm.unique_pokemon_id==Pokemon.id,
+        and_(PokemonForm.unique_pokemon_id==None, 
+            PokemonForm.form_base_pokemon_id==Pokemon.id,
+            PokemonForm.is_default==True)
+        ),
+        uselist=False)
 
 PokemonDexNumber.pokedex = relation(Pokedex,
     innerjoin=True, lazy='joined')
 
 
 PokemonDexNumber.pokedex = relation(Pokedex,
     innerjoin=True, lazy='joined')
 
-PokemonEvolution.from_pokemon = relation(Pokemon,
-    primaryjoin=PokemonEvolution.from_pokemon_id==Pokemon.id,
-    innerjoin=True,
-    backref='child_evolutions')
-PokemonEvolution.to_pokemon = relation(Pokemon,
-    primaryjoin=PokemonEvolution.to_pokemon_id==Pokemon.id,
-    innerjoin=True,
-    backref=backref('parent_evolution', uselist=False))
-PokemonEvolution.child_evolutions = relation(PokemonEvolution,
-    primaryjoin=PokemonEvolution.from_pokemon_id==PokemonEvolution.to_pokemon_id,
-    foreign_keys=[PokemonEvolution.to_pokemon_id],
-    backref=backref('parent_evolution',
-        remote_side=[PokemonEvolution.from_pokemon_id],
-        uselist=False))
 PokemonEvolution.trigger = relation(EvolutionTrigger,
     innerjoin=True, lazy='joined',
     backref='evolutions')
 PokemonEvolution.trigger = relation(EvolutionTrigger,
     innerjoin=True, lazy='joined',
     backref='evolutions')
@@ -2090,6 +2055,12 @@ PokemonForm.form_base_pokemon = relation(Pokemon,
 PokemonForm.unique_pokemon = relation(Pokemon,
     primaryjoin=PokemonForm.unique_pokemon_id==Pokemon.id,
     backref=backref('unique_form', uselist=False))
 PokemonForm.unique_pokemon = relation(Pokemon,
     primaryjoin=PokemonForm.unique_pokemon_id==Pokemon.id,
     backref=backref('unique_form', uselist=False))
+PokemonForm.pokemon = relation(Pokemon,
+    primaryjoin=or_(
+        PokemonForm.unique_pokemon_id==Pokemon.id,
+        and_(PokemonForm.unique_pokemon_id==None, 
+            PokemonForm.form_base_pokemon_id==Pokemon.id)
+        ), uselist=False)
 PokemonForm.version_group = relation(VersionGroup,
     innerjoin=True)
 PokemonForm.form_group = association_proxy('form_base_pokemon', 'form_group')
 PokemonForm.version_group = relation(VersionGroup,
     innerjoin=True)
 PokemonForm.form_group = association_proxy('form_base_pokemon', 'form_group')