veekun_pokedex/pokedex/db/tables.py

640 lines
30 KiB
Python

# encoding: utf8
from sqlalchemy import Column, ForeignKey, MetaData, Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import backref, relation
from sqlalchemy.sql import and_
from sqlalchemy.types import *
from sqlalchemy.databases.mysql import *
from pokedex.db import rst
metadata = MetaData()
TableBase = declarative_base(metadata=metadata)
class Ability(TableBase):
__tablename__ = 'abilities'
__singlename__ = 'ability'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(24), nullable=False)
flavor_text = Column(Unicode(64), nullable=False)
effect = Column(Unicode(255), nullable=False)
class ContestCombo(TableBase):
__tablename__ = '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)
class ContestEffect(TableBase):
__tablename__ = 'contest_effects'
id = Column(Integer, primary_key=True, nullable=False)
appeal = Column(SmallInteger, nullable=False)
jam = Column(SmallInteger, nullable=False)
flavor_text = Column(Unicode(64), nullable=False)
effect = Column(Unicode(255), nullable=False)
class EggGroup(TableBase):
__tablename__ = 'egg_groups'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(16), nullable=False)
class Encounter(TableBase):
"""Rows in this table represent encounters with wild Pokémon. Bear with
me, here.
Within a given area in a given game, encounters are differentiated by the
"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
encounter slots.
Within a terrain, 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
swarm" are the possible values of this condition.
A slot (20% walking in grass) and any appropriate world conditions (no
swarm) are thus enough to define a specific encounter.
Well, okay, almost: each slot actually appears twice.
"""
__tablename__ = 'encounters'
id = Column(Integer, primary_key=True, nullable=False)
version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False)
location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False)
encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), nullable=False, autoincrement=False)
pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False)
min_level = Column(Integer, nullable=False, autoincrement=False)
max_level = Column(Integer, nullable=False, autoincrement=False)
class EncounterCondition(TableBase):
"""Rows in this table represent varying conditions in the game world, such
as time of day.
"""
__tablename__ = 'encounter_conditions'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(64), nullable=False)
class EncounterConditionValue(TableBase):
"""Rows in this table represent possible states for a condition; for
example, the state of 'swarm' could be 'swarm' or 'no swarm'.
"""
__tablename__ = 'encounter_condition_values'
id = Column(Integer, primary_key=True, nullable=False)
encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=False, nullable=False, autoincrement=False)
name = Column(Unicode(64), nullable=False)
is_default = Column(Boolean, nullable=False)
class EncounterConditionValueMap(TableBase):
"""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)
encounter_condition_value_id = Column(Integer, ForeignKey('encounter_condition_values.id'), primary_key=True, nullable=False, autoincrement=False)
class EncounterTerrain(TableBase):
"""Rows in this table represent ways the player can enter a wild encounter,
e.g., surfing, fishing, or walking through tall grass.
"""
__tablename__ = 'encounter_terrain'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(64), nullable=False)
class EncounterSlot(TableBase):
"""Rows in this table represent 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.
"""
__tablename__ = 'encounter_slots'
id = Column(Integer, primary_key=True, nullable=False)
version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, autoincrement=False)
encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=False, nullable=False, autoincrement=False)
rarity = Column(Integer, nullable=False, autoincrement=False)
class EncounterSlotCondition(TableBase):
"""Lists all conditions that affect each slot."""
__tablename__ = 'encounter_slot_conditions'
encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), primary_key=True, nullable=False, autoincrement=False)
encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=True, nullable=False, autoincrement=False)
class EvolutionChain(TableBase):
__tablename__ = 'evolution_chains'
id = Column(Integer, primary_key=True, nullable=False)
growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), nullable=False)
steps_to_hatch = Column(Integer, nullable=False)
baby_trigger_item = Column(Unicode(12))
class EvolutionMethod(TableBase):
__tablename__ = 'evolution_methods'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(64), nullable=False)
description = Column(Unicode(255), nullable=False)
class Generation(TableBase):
__tablename__ = 'generations'
id = Column(Integer, primary_key=True, nullable=False)
main_region_id = Column(Integer, ForeignKey('regions.id'))
name = Column(Unicode(16), nullable=False)
class GrowthRate(TableBase):
"""`formula` is written in LaTeX math notation."""
__tablename__ = 'growth_rates'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(20), nullable=False)
formula = Column(Unicode(500), nullable=False)
class Item(TableBase):
__tablename__ = 'items'
__singlename__ = 'item'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(16), nullable=False)
class Language(TableBase):
__tablename__ = 'languages'
id = Column(Integer, primary_key=True, nullable=False)
iso3166 = Column(Unicode(2), nullable=False)
name = Column(Unicode(16), nullable=False)
class Location(TableBase):
__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)
class LocationArea(TableBase):
__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)
class LocationAreaEncounterRate(TableBase):
__tablename__ = 'location_area_encounter_rates'
location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
encounter_type_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
rate = Column(Integer, nullable=True)
class Machine(TableBase):
__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)
move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
class MoveEffectCategory(TableBase):
__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)
class MoveEffectCategoryMap(TableBase):
__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)
class MoveDamageClass(TableBase):
__tablename__ = 'move_damage_classes'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(8), nullable=False)
description = Column(Unicode(64), nullable=False)
class MoveEffect(TableBase):
__tablename__ = 'move_effects'
id = Column(Integer, primary_key=True, nullable=False)
priority = Column(SmallInteger, nullable=False)
short_effect = Column(Unicode(256), nullable=False)
effect = Column(Unicode(5120), nullable=False)
class MoveFlag(TableBase):
__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)
class MoveFlagType(TableBase):
__tablename__ = 'move_flag_types'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(32), nullable=False)
description = Column(rst.RstTextColumn(128), nullable=False)
class MoveFlavorText(TableBase):
__tablename__ = 'move_flavor_text'
move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, nullable=False, autoincrement=False)
flavor_text = Column(Unicode(255), nullable=False)
class MoveName(TableBase):
__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)
class MoveTarget(TableBase):
__tablename__ = 'move_targets'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(32), nullable=False)
description = Column(Unicode(128), nullable=False)
class Move(TableBase):
__tablename__ = 'moves'
__singlename__ = 'move'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(12), nullable=False)
generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
power = Column(SmallInteger)
pp = Column(SmallInteger, nullable=False)
accuracy = Column(SmallInteger)
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 = Column(Unicode(8), nullable=False)
contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True)
super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=False)
class Pokedex(TableBase):
__tablename__ = 'pokedexes'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(16), nullable=False)
description = Column(Unicode(512))
class PokedexVersionGroup(TableBase):
__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)
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.
"""
__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'))
evolution_parent_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
evolution_method_id = Column(Integer, ForeignKey('evolution_methods.id'))
evolution_parameter = Column(Unicode(32))
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=False)
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)
has_gen4_fem_sprite = Column(Boolean, nullable=False)
has_gen4_fem_back_sprite = Column(Boolean, nullable=False)
### 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.
"""
if self.forme_base_pokemon_id:
return self.forme_base_pokemon_id
return self.id
@property
def full_name(self):
"""Returns the name of this Pokémon, including its Forme, if any."""
if self.forme_name:
return "%s %s" % (self.forme_name.capitalize(), self.name)
return self.name
@property
def normal_form(self):
"""Returns the normal form for this Pokémon; i.e., this will return
regular Deoxys when called on any Deoxys form.
"""
if self.forme_base_pokemon:
return self.forme_base_pokemon
return self
class PokemonAbility(TableBase):
__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)
class PokemonColor(TableBase):
__tablename__ = 'pokemon_colors'
id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
name = Column(Unicode(6), nullable=False)
class PokemonDexNumber(TableBase):
__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)
class PokemonEggGroup(TableBase):
__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)
class PokemonFlavorText(TableBase):
__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)
class PokemonFormGroup(TableBase):
__tablename__ = 'pokemon_form_groups'
pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
description = Column(Unicode(512), 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)
class PokemonHabitat(TableBase):
__tablename__ = 'pokemon_habitats'
id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
name = Column(Unicode(16), nullable=False)
class PokemonItem(TableBase):
__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)
class PokemonMove(TableBase):
__tablename__ = 'pokemon_moves'
pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False, index=True)
pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), primary_key=True, nullable=False, autoincrement=False)
level = Column(Integer, primary_key=True, nullable=True, autoincrement=False)
order = Column(Integer, nullable=True)
class PokemonMoveMethod(TableBase):
__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)
class PokemonName(TableBase):
__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)
class PokemonShape(TableBase):
__tablename__ = 'pokemon_shapes'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(24), nullable=False)
awesome_name = Column(Unicode(16), nullable=False)
class PokemonStat(TableBase):
__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)
class PokemonType(TableBase):
__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)
class Region(TableBase):
"""Major areas of the world: Kanto, Johto, etc."""
__tablename__ = 'regions'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(16), nullable=False)
class Stat(TableBase):
__tablename__ = 'stats'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(Unicode(16), nullable=False)
class SuperContestCombo(TableBase):
__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)
class SuperContestEffect(TableBase):
__tablename__ = 'super_contest_effects'
id = Column(Integer, primary_key=True, nullable=False)
appeal = Column(SmallInteger, nullable=False)
flavor_text = Column(Unicode(64), nullable=False)
class TypeEfficacy(TableBase):
__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)
class Type(TableBase):
__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
class VersionGroup(TableBase):
__tablename__ = 'version_groups'
id = Column(Integer, primary_key=True, nullable=False)
generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
class VersionGroupRegion(TableBase):
__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)
class Version(TableBase):
__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)
### Relations down here, to avoid ordering problems
ContestCombo.first = relation(Move, primaryjoin=ContestCombo.first_move_id==Move.id,
backref='contest_combo_first')
ContestCombo.second = relation(Move, primaryjoin=ContestCombo.second_move_id==Move.id,
backref='contest_combo_second')
Encounter.location_area = relation(LocationArea, backref='encounters')
Encounter.pokemon = relation(Pokemon, backref='encounters')
Encounter.version = relation(Version, backref='encounters')
Encounter.slot = relation(EncounterSlot, backref='encounters')
EncounterConditionValue.condition = relation(EncounterCondition, backref='values')
Encounter.condition_value_map = relation(EncounterConditionValueMap, backref='encounter')
Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
backref='encounter_map')
EncounterSlot.terrain = relation(EncounterTerrain, backref='slots')
EncounterSlot.condition_map = relation(EncounterSlotCondition, backref='slot')
EncounterSlot.conditions = association_proxy('condition_map', 'condition')
EncounterSlotCondition.condition = relation(EncounterCondition,
backref='slot_map')
EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')
Generation.versions = relation(Version, secondary=VersionGroup.__table__)
Generation.main_region = relation(Region)
Location.region = relation(Region, backref='locations')
LocationArea.location = relation(Location, backref='areas')
Machine.version_group = relation(VersionGroup)
Move.contest_effect = relation(ContestEffect, backref='moves')
Move.contest_combo_next = association_proxy('contest_combo_first', 'second')
Move.contest_combo_prev = association_proxy('contest_combo_second', 'first')
Move.damage_class = relation(MoveDamageClass, backref='moves')
Move.flags = association_proxy('move_flags', 'flag')
Move.flavor_text = relation(MoveFlavorText, order_by=MoveFlavorText.generation_id, backref='move')
Move.foreign_names = relation(MoveName, backref='pokemon')
Move.generation = relation(Generation, backref='moves')
Move.machines = relation(Machine, backref='move')
Move.move_effect = relation(MoveEffect, backref='moves')
Move.move_flags = relation(MoveFlag, backref='move')
Move.super_contest_effect = relation(SuperContestEffect, backref='moves')
Move.super_contest_combo_next = association_proxy('super_contest_combo_first', 'second')
Move.super_contest_combo_prev = association_proxy('super_contest_combo_second', 'first')
Move.target = relation(MoveTarget, backref='moves')
Move.type = relation(Type, backref='moves')
Move.effect = rst.MoveEffectProperty('effect')
Move.priority = association_proxy('move_effect', 'priority')
Move.short_effect = rst.MoveEffectProperty('short_effect')
MoveEffect.category_map = relation(MoveEffectCategoryMap)
MoveEffect.categories = association_proxy('category_map', 'category')
MoveEffectCategoryMap.category = relation(MoveEffectCategory)
MoveFlag.flag = relation(MoveFlagType)
MoveFlavorText.generation = relation(Generation)
MoveName.language = relation(Language)
Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__)
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.pokemon_color = relation(PokemonColor, backref='pokemon')
Pokemon.color = association_proxy('pokemon_color', 'name')
Pokemon.dex_numbers = relation(PokemonDexNumber, backref='pokemon')
Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
order_by=PokemonEggGroup.egg_group_id,
backref='pokemon')
Pokemon.evolution_chain = relation(EvolutionChain, backref='pokemon')
Pokemon.evolution_method = relation(EvolutionMethod)
Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
backref=backref('evolution_parent',
remote_side=[Pokemon.id]))
Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.pokemon_id, backref='pokemon')
Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
Pokemon.items = relation(PokemonItem)
Pokemon.generation = relation(Generation, backref='pokemon')
Pokemon.shape = relation(PokemonShape, backref='pokemon')
Pokemon.stats = relation(PokemonStat, backref='pokemon')
Pokemon.types = relation(Type, secondary=PokemonType.__table__)
PokemonDexNumber.pokedex = relation(Pokedex)
PokemonFlavorText.version = relation(Version)
PokemonItem.item = relation(Item, backref='pokemon')
PokemonItem.version = relation(Version)
PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
uselist=False))
PokemonFormSprite.pokemon = relation(Pokemon, backref='form_sprites')
PokemonFormSprite.introduced_in = relation(VersionGroup)
PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
PokemonMove.version_group = relation(VersionGroup)
PokemonMove.machine = relation(Machine, backref='pokemon_moves',
primaryjoin=and_(Machine.version_group_id==PokemonMove.version_group_id,
Machine.move_id==PokemonMove.move_id),
foreign_keys=[Machine.version_group_id, Machine.move_id],
uselist=False)
PokemonMove.move = relation(Move, backref='pokemon_moves')
PokemonMove.method = relation(PokemonMoveMethod)
PokemonName.language = relation(Language)
PokemonStat.stat = relation(Stat)
# This is technically a has-many; Generation.main_region_id -> Region.id
Region.generation = relation(Generation, uselist=False)
Region.version_group_regions = relation(VersionGroupRegion, backref='region',
order_by='VersionGroupRegion.version_group_id')
Region.version_groups = association_proxy('version_group_regions', 'version_group')
SuperContestCombo.first = relation(Move, primaryjoin=SuperContestCombo.first_move_id==Move.id,
backref='super_contest_combo_first')
SuperContestCombo.second = relation(Move, primaryjoin=SuperContestCombo.second_move_id==Move.id,
backref='super_contest_combo_second')
Type.damage_efficacies = relation(TypeEfficacy,
primaryjoin=Type.id
==TypeEfficacy.damage_type_id,
backref='damage_type')
Type.target_efficacies = relation(TypeEfficacy,
primaryjoin=Type.id
==TypeEfficacy.target_type_id,
backref='target_type')
Type.generation = relation(Generation, backref='types')
Type.damage_class = relation(MoveDamageClass, backref='types')
Version.version_group = relation(VersionGroup, backref='versions')
Version.generation = association_proxy('version_group', 'generation')
VersionGroup.generation = relation(Generation, backref='version_groups')
VersionGroup.version_group_regions = relation(VersionGroupRegion, backref='version_group')
VersionGroup.regions = association_proxy('version_group_regions', 'region')