3 from sqlalchemy
import Column
, ForeignKey
, MetaData
, Table
4 from sqlalchemy
.ext
.declarative
import declarative_base
5 from sqlalchemy
.ext
.associationproxy
import association_proxy
6 from sqlalchemy
.orm
import backref
, relation
7 from sqlalchemy
.types
import *
8 from sqlalchemy
.databases
.mysql
import *
10 from pokedex
.db
import rst
13 TableBase
= declarative_base(metadata
=metadata
)
15 class Ability(TableBase
):
16 __tablename__
= 'abilities'
17 __singlename__
= 'ability'
18 id = Column(Integer
, primary_key
=True, nullable
=False)
19 name
= Column(Unicode(24), nullable
=False)
20 flavor_text
= Column(Unicode(64), nullable
=False)
21 effect
= Column(Unicode(255), nullable
=False)
23 class ContestEffect(TableBase
):
24 __tablename__
= 'contest_effects'
25 id = Column(Integer
, primary_key
=True, nullable
=False)
26 appeal
= Column(SmallInteger
, nullable
=False)
27 jam
= Column(SmallInteger
, nullable
=False)
28 flavor
= Column(Unicode(255), nullable
=False)
29 effect
= Column(Unicode(255), nullable
=False)
31 class EggGroup(TableBase
):
32 __tablename__
= 'egg_groups'
33 id = Column(Integer
, primary_key
=True, nullable
=False)
34 name
= Column(Unicode(16), nullable
=False)
36 class Encounter(TableBase
):
37 """Rows in this table represent encounters with wild Pokémon.
39 Within a given area in a given game, encounters are differentiated by the
40 slot they are in and a world condition.
42 Groups of slots belong to encounter types; these are what the player is
43 doing to get an encounter, such as surfing or walking through tall grass.
45 Within an encounter type, slots are defined primarily by rarity. Each slot
46 can also be affected by a world condition; for example, the 20% slot for
47 walking in tall grass is affected by whether a swarm is in effect in the
48 areas. "There is a swarm" and "there is not a swarm" are conditions, and
49 together they make a condition group. However, since "not a swarm" is a
50 base state rather than any sort of new state, it is omitted and instead
51 referred to by a NULL.
53 A slot (20% walking in grass) and single world condition (NULL, i.e. no
54 swarm) are thus enough to define a specific encounter.
56 Well, okay, almost: each slot actually appears twice.
59 __tablename__
= 'encounters'
60 id = Column(Integer
, primary_key
=True, nullable
=False)
61 version_id
= Column(Integer
, ForeignKey('versions.id'), nullable
=False, autoincrement
=False)
62 location_area_id
= Column(Integer
, ForeignKey('location_areas.id'), nullable
=False, autoincrement
=False)
63 encounter_type_slot_id
= Column(Integer
, ForeignKey('encounter_type_slots.id'), nullable
=False, autoincrement
=False)
64 encounter_condition_id
= Column(Integer
, ForeignKey('encounter_conditions.id'), nullable
=True, autoincrement
=False)
65 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), nullable
=False, autoincrement
=False)
66 min_level
= Column(Integer
, nullable
=False, autoincrement
=False)
67 max_level
= Column(Integer
, nullable
=False, autoincrement
=False)
69 class EncounterCondition(TableBase
):
70 """Rows in this table represent something different about the world that
71 can affect what Pokémon are encountered.
74 __tablename__
= 'encounter_conditions'
75 id = Column(Integer
, primary_key
=True, nullable
=False)
76 encounter_condition_group_id
= Column(Integer
, ForeignKey('encounter_condition_groups.id'), primary_key
=False, nullable
=False, autoincrement
=False)
77 name
= Column(Unicode(64), nullable
=False)
79 class EncounterConditionGroup(TableBase
):
80 """Rows in this table represent a group of mutually exclusive conditions,
81 such as morning/day/night. "Conditions" that are part of the default state
82 of the world, such as "not during a swarm" or "not using the PokéRadar",
83 are not included in this table and are referred to by NULLs in other
87 __tablename__
= 'encounter_condition_groups'
88 id = Column(Integer
, primary_key
=True, nullable
=False)
89 name
= Column(Unicode(64), nullable
=False)
91 class EncounterType(TableBase
):
92 """Rows in this table represent ways the player can enter a wild encounter;
93 i.e. surfing, fishing, or walking through tall grass.
96 __tablename__
= 'encounter_types'
97 id = Column(Integer
, primary_key
=True, nullable
=False)
98 name
= Column(Unicode(64), nullable
=False)
100 class EncounterTypeSlot(TableBase
):
101 """Rows in this table represent an abstract "slot" within an encounter
102 type, associated with both a condition group and a rarity.
104 Note that there are two encounters per slot, so the rarities will only add
108 __tablename__
= 'encounter_type_slots'
109 id = Column(Integer
, primary_key
=True, nullable
=False)
110 encounter_type_id
= Column(Integer
, ForeignKey('encounter_types.id'), primary_key
=False, nullable
=False, autoincrement
=False)
111 encounter_condition_group_id
= Column(Integer
, ForeignKey('encounter_condition_groups.id'), primary_key
=False, nullable
=True, autoincrement
=False)
112 rarity
= Column(Integer
, nullable
=False, autoincrement
=False)
114 class EvolutionChain(TableBase
):
115 __tablename__
= 'evolution_chains'
116 id = Column(Integer
, primary_key
=True, nullable
=False)
117 growth_rate_id
= Column(Integer
, ForeignKey('growth_rates.id'), nullable
=False)
118 steps_to_hatch
= Column(Integer
, nullable
=False)
119 baby_trigger_item
= Column(Unicode(12))
121 class EvolutionMethod(TableBase
):
122 __tablename__
= 'evolution_methods'
123 id = Column(Integer
, primary_key
=True, nullable
=False)
124 name
= Column(Unicode(64), nullable
=False)
125 description
= Column(Unicode(255), nullable
=False)
127 class Generation(TableBase
):
128 __tablename__
= 'generations'
129 id = Column(Integer
, primary_key
=True, nullable
=False)
130 name
= Column(Unicode(16), nullable
=False)
131 main_region
= Column(Unicode(16), nullable
=False)
133 class GrowthRate(TableBase
):
134 """`formula` is written in LaTeX math notation."""
135 __tablename__
= 'growth_rates'
136 id = Column(Integer
, primary_key
=True, nullable
=False)
137 name
= Column(Unicode(20), nullable
=False)
138 formula
= Column(Unicode(500), nullable
=False)
140 class Item(TableBase
):
141 __tablename__
= 'items'
142 __singlename__
= 'item'
143 id = Column(Integer
, primary_key
=True, nullable
=False)
144 name
= Column(Unicode(16), nullable
=False)
146 class Language(TableBase
):
147 __tablename__
= 'languages'
148 id = Column(Integer
, primary_key
=True, nullable
=False)
149 name
= Column(Unicode(16), nullable
=False)
151 class Location(TableBase
):
152 __tablename__
= 'locations'
153 __singlename__
= 'location'
154 id = Column(Integer
, primary_key
=True, nullable
=False)
155 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
156 name
= Column(Unicode(64), nullable
=False)
158 class LocationArea(TableBase
):
159 __tablename__
= 'location_areas'
160 id = Column(Integer
, primary_key
=True, nullable
=False)
161 location_id
= Column(Integer
, ForeignKey('locations.id'), nullable
=False)
162 internal_id
= Column(Integer
, nullable
=False)
163 name
= Column(Unicode(64), nullable
=True)
165 class LocationAreaEncounterRate(TableBase
):
166 __tablename__
= 'location_area_encounter_rates'
167 location_area_id
= Column(Integer
, ForeignKey('location_areas.id'), primary_key
=True, nullable
=False, autoincrement
=False)
168 encounter_type_id
= Column(Integer
, ForeignKey('encounter_types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
169 rate
= Column(Integer
, nullable
=True)
171 class Machine(TableBase
):
172 __tablename__
= 'machines'
173 machine_number
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
174 generation_id
= Column(Integer
, ForeignKey('generations.id'), primary_key
=True, nullable
=False, autoincrement
=False)
175 move_id
= Column(Integer
, ForeignKey('moves.id'), nullable
=False)
177 class MoveDamageClass(TableBase
):
178 __tablename__
= 'move_damage_classes'
179 id = Column(Integer
, primary_key
=True, nullable
=False)
180 name
= Column(Unicode(8), nullable
=False)
181 description
= Column(Unicode(64), nullable
=False)
183 class MoveEffect(TableBase
):
184 __tablename__
= 'move_effects'
185 id = Column(Integer
, primary_key
=True, nullable
=False)
186 priority
= Column(SmallInteger
, nullable
=False)
187 short_effect
= Column(Unicode(256), nullable
=False)
188 effect
= Column(Unicode(5120), nullable
=False)
190 class MoveFlag(TableBase
):
191 __tablename__
= 'move_flags'
192 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
193 move_flag_type_id
= Column(Integer
, ForeignKey('move_flag_types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
195 class MoveFlagType(TableBase
):
196 __tablename__
= 'move_flag_types'
197 id = Column(Integer
, primary_key
=True, nullable
=False)
198 name
= Column(Unicode(32), nullable
=False)
199 description
= Column(rst
.RstTextColumn(128), nullable
=False)
201 class MoveName(TableBase
):
202 __tablename__
= 'move_names'
203 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
204 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
205 name
= Column(Unicode(16), nullable
=False)
207 class MoveTarget(TableBase
):
208 __tablename__
= 'move_targets'
209 id = Column(Integer
, primary_key
=True, nullable
=False)
210 name
= Column(Unicode(32), nullable
=False)
211 description
= Column(Unicode(128), nullable
=False)
213 class Move(TableBase
):
214 __tablename__
= 'moves'
215 __singlename__
= 'move'
216 id = Column(Integer
, primary_key
=True, nullable
=False)
217 name
= Column(Unicode(12), nullable
=False)
218 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
219 type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=False)
220 power
= Column(SmallInteger
)
221 pp
= Column(SmallInteger
, nullable
=False)
222 accuracy
= Column(SmallInteger
)
223 target_id
= Column(Integer
, ForeignKey('move_targets.id'), nullable
=False)
224 damage_class_id
= Column(Integer
, ForeignKey('move_damage_classes.id'), nullable
=False)
225 effect_id
= Column(Integer
, ForeignKey('move_effects.id'), nullable
=False)
226 effect_chance
= Column(Integer
)
227 contest_type
= Column(Unicode(8), nullable
=False)
228 contest_effect_id
= Column(Integer
, ForeignKey('contest_effects.id'), nullable
=True)
229 super_contest_effect_id
= Column(Integer
, nullable
=False)
231 class Pokemon(TableBase
):
232 """The core to this whole mess.
234 Note that I use both 'forme' and 'form' in both code and the database. I
235 only use 'forme' when specifically referring to Pokémon that have multiple
236 distinct species as forms—i.e., different stats or movesets. 'Form' is a
237 more general term referring to any variation within a species, including
238 purely cosmetic forms like Unown.
240 __tablename__
= 'pokemon'
241 __singlename__
= 'pokemon'
242 id = Column(Integer
, primary_key
=True, nullable
=False)
243 name
= Column(Unicode(20), nullable
=False)
244 forme_name
= Column(Unicode(16))
245 forme_base_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'))
246 generation_id
= Column(Integer
, ForeignKey('generations.id'))
247 evolution_chain_id
= Column(Integer
, ForeignKey('evolution_chains.id'))
248 evolution_parent_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'))
249 evolution_method_id
= Column(Integer
, ForeignKey('evolution_methods.id'))
250 evolution_parameter
= Column(Unicode(32))
251 height
= Column(Integer
, nullable
=False)
252 weight
= Column(Integer
, nullable
=False)
253 species
= Column(Unicode(16), nullable
=False)
254 color
= Column(Unicode(6), nullable
=False)
255 pokemon_shape_id
= Column(Integer
, ForeignKey('pokemon_shapes.id'), nullable
=False)
256 habitat
= Column(Unicode(16), nullable
=False)
257 gender_rate
= Column(Integer
, nullable
=False)
258 capture_rate
= Column(Integer
, nullable
=False)
259 base_experience
= Column(Integer
, nullable
=False)
260 base_happiness
= Column(Integer
, nullable
=False)
261 gen1_internal_id
= Column(Integer
)
262 is_baby
= Column(Boolean
, nullable
=False)
263 has_gen4_fem_sprite
= Column(Boolean
, nullable
=False)
264 has_gen4_fem_back_sprite
= Column(Boolean
, nullable
=False)
266 ### Stuff to handle alternate Pokémon forms
269 def national_id(self
):
270 """Returns the National Pokédex number for this Pokémon. Use this
271 instead of the id directly; alternate formes may make the id incorrect.
274 if self
.forme_base_pokemon_id
:
275 return self
.forme_base_pokemon_id
280 """Returns the name of this Pokémon, including its Forme, if any."""
283 return "%s %s" %
(self
.forme_name
.capitalize(), self
.name
)
287 def normal_form(self
):
288 """Returns the normal form for this Pokémon; i.e., this will return
289 regular Deoxys when called on any Deoxys form.
292 if self
.forme_base_pokemon
:
293 return self
.forme_base_pokemon
297 class PokemonAbility(TableBase
):
298 __tablename__
= 'pokemon_abilities'
299 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
300 ability_id
= Column(Integer
, ForeignKey('abilities.id'), nullable
=False)
301 slot
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
303 class PokemonDexNumber(TableBase
):
304 __tablename__
= 'pokemon_dex_numbers'
305 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
306 generation_id
= Column(Integer
, ForeignKey('generations.id'), primary_key
=True, nullable
=False, autoincrement
=False)
307 pokedex_number
= Column(Integer
, nullable
=False)
309 class PokemonEggGroup(TableBase
):
310 __tablename__
= 'pokemon_egg_groups'
311 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
312 egg_group_id
= Column(Integer
, ForeignKey('egg_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
314 class PokemonFlavorText(TableBase
):
315 __tablename__
= 'pokemon_flavor_text'
316 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
317 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
318 flavor_text
= Column(Unicode(255), nullable
=False)
320 class PokemonFormGroup(TableBase
):
321 __tablename__
= 'pokemon_form_groups'
322 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
323 description
= Column(Unicode(512), nullable
=False)
325 class PokemonFormSprite(TableBase
):
326 __tablename__
= 'pokemon_form_sprites'
327 id = Column(Integer
, primary_key
=True, nullable
=False)
328 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
329 name
= Column(Unicode(16), nullable
=True)
331 class PokemonItem(TableBase
):
332 __tablename__
= 'pokemon_items'
333 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
334 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
335 item_id
= Column(Integer
, ForeignKey('items.id'), primary_key
=True, nullable
=False, autoincrement
=False)
336 rarity
= Column(Integer
, nullable
=False)
338 class PokemonMove(TableBase
):
339 __tablename__
= 'pokemon_moves'
340 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
341 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
342 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False, index
=True)
343 pokemon_move_method_id
= Column(Integer
, ForeignKey('pokemon_move_methods.id'), primary_key
=True, nullable
=False, autoincrement
=False)
344 level
= Column(Integer
, primary_key
=True, nullable
=True, autoincrement
=False)
345 order
= Column(Integer
, nullable
=True)
347 class PokemonMoveMethod(TableBase
):
348 __tablename__
= 'pokemon_move_methods'
349 id = Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
350 name
= Column(Unicode(64), nullable
=False)
351 description
= Column(Unicode(255), nullable
=False)
353 class PokemonName(TableBase
):
354 __tablename__
= 'pokemon_names'
355 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
356 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
357 name
= Column(Unicode(16), nullable
=False)
359 class PokemonShape(TableBase
):
360 __tablename__
= 'pokemon_shapes'
361 id = Column(Integer
, primary_key
=True, nullable
=False)
362 name
= Column(Unicode(24), nullable
=False)
363 awesome_name
= Column(Unicode(16), nullable
=False)
365 class PokemonStat(TableBase
):
366 __tablename__
= 'pokemon_stats'
367 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
368 stat_id
= Column(Integer
, ForeignKey('stats.id'), primary_key
=True, nullable
=False, autoincrement
=False)
369 base_stat
= Column(Integer
, nullable
=False)
370 effort
= Column(Integer
, nullable
=False)
372 class PokemonType(TableBase
):
373 __tablename__
= 'pokemon_types'
374 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
375 type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=False)
376 slot
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
378 class Stat(TableBase
):
379 __tablename__
= 'stats'
380 id = Column(Integer
, primary_key
=True, nullable
=False)
381 name
= Column(Unicode(16), nullable
=False)
383 class TypeEfficacy(TableBase
):
384 __tablename__
= 'type_efficacy'
385 damage_type_id
= Column(Integer
, ForeignKey('types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
386 target_type_id
= Column(Integer
, ForeignKey('types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
387 damage_factor
= Column(Integer
, nullable
=False)
389 class Type(TableBase
):
390 __tablename__
= 'types'
391 __singlename__
= 'type'
392 id = Column(Integer
, primary_key
=True, nullable
=False)
393 name
= Column(Unicode(8), nullable
=False)
394 abbreviation
= Column(Unicode(3), nullable
=False)
396 class VersionGroup(TableBase
):
397 __tablename__
= 'version_groups'
398 id = Column(Integer
, primary_key
=True, nullable
=False)
399 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
401 class Version(TableBase
):
402 __tablename__
= 'versions'
403 id = Column(Integer
, primary_key
=True, nullable
=False)
404 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), nullable
=False)
405 name
= Column(Unicode(32), nullable
=False)
408 ### Relations down here, to avoid ordering problems
409 Encounter
.pokemon
= relation(Pokemon
, backref
='encounters')
410 Encounter
.version
= relation(Version
, backref
='encounters')
411 Encounter
.location_area
= relation(LocationArea
, backref
='encounters')
412 Encounter
.slot
= relation(EncounterTypeSlot
, backref
='encounters')
413 Encounter
.condition
= relation(EncounterCondition
, backref
='encounters')
415 EncounterCondition
.group
= relation(EncounterConditionGroup
,
416 backref
='conditions')
418 EncounterTypeSlot
.type = relation(EncounterType
, backref
='slots')
420 EvolutionChain
.growth_rate
= relation(GrowthRate
, backref
='evolution_chains')
422 Generation
.versions
= relation(Version
, secondary
=VersionGroup
.__table__
)
424 LocationArea
.location
= relation(Location
, backref
='areas')
426 Machine
.generation
= relation(Generation
)
428 Move
.damage_class
= relation(MoveDamageClass
, backref
='moves')
429 Move
.flags
= association_proxy('move_flags', 'flag')
430 Move
.foreign_names
= relation(MoveName
, backref
='pokemon')
431 Move
.generation
= relation(Generation
, backref
='moves')
432 Move
.machines
= relation(Machine
, backref
='move')
433 Move
.move_effect
= relation(MoveEffect
, backref
='moves')
434 Move
.move_flags
= relation(MoveFlag
, backref
='move')
435 Move
.target
= relation(MoveTarget
, backref
='moves')
436 Move
.type = relation(Type
, backref
='moves')
438 Move
.effect
= rst
.MoveEffectProperty('effect')
439 Move
.priority
= association_proxy('move_effect', 'priority')
440 Move
.short_effect
= rst
.MoveEffectProperty('short_effect')
442 MoveFlag
.flag
= relation(MoveFlagType
)
444 MoveName
.language
= relation(Language
)
446 Pokemon
.abilities
= relation(Ability
, secondary
=PokemonAbility
.__table__
,
447 order_by
=PokemonAbility
.slot
,
449 Pokemon
.formes
= relation(Pokemon
, primaryjoin
=Pokemon
.id==Pokemon
.forme_base_pokemon_id
,
450 backref
=backref('forme_base_pokemon',
451 remote_side
=[Pokemon
.id]))
452 Pokemon
.dex_numbers
= relation(PokemonDexNumber
, backref
='pokemon')
453 Pokemon
.egg_groups
= relation(EggGroup
, secondary
=PokemonEggGroup
.__table__
,
454 order_by
=PokemonEggGroup
.egg_group_id
,
456 Pokemon
.evolution_chain
= relation(EvolutionChain
, backref
='pokemon')
457 Pokemon
.evolution_method
= relation(EvolutionMethod
)
458 Pokemon
.evolution_children
= relation(Pokemon
, primaryjoin
=Pokemon
.id==Pokemon
.evolution_parent_pokemon_id
,
459 backref
=backref('evolution_parent',
460 remote_side
=[Pokemon
.id]))
461 Pokemon
.flavor_text
= relation(PokemonFlavorText
, backref
='pokemon')
462 Pokemon
.foreign_names
= relation(PokemonName
, backref
='pokemon')
463 Pokemon
.items
= relation(PokemonItem
)
464 Pokemon
.generation
= relation(Generation
, backref
='pokemon')
465 Pokemon
.shape
= relation(PokemonShape
, backref
='pokemon')
466 Pokemon
.stats
= relation(PokemonStat
, backref
='pokemon')
467 Pokemon
.types
= relation(Type
, secondary
=PokemonType
.__table__
)
469 PokemonDexNumber
.generation
= relation(Generation
)
471 PokemonFlavorText
.version
= relation(Version
)
473 PokemonItem
.item
= relation(Item
, backref
='pokemon')
474 PokemonItem
.version
= relation(Version
)
476 PokemonFormGroup
.pokemon
= relation(Pokemon
, backref
=backref('form_group',
478 PokemonFormSprite
.pokemon
= relation(Pokemon
, backref
='form_sprites')
480 PokemonMove
.pokemon
= relation(Pokemon
, backref
='pokemon_moves')
481 PokemonMove
.version_group
= relation(VersionGroup
)
482 PokemonMove
.move
= relation(Move
, backref
='pokemon_moves')
483 PokemonMove
.method
= relation(PokemonMoveMethod
)
485 PokemonName
.language
= relation(Language
)
487 PokemonStat
.stat
= relation(Stat
)
489 Type
.damage_efficacies
= relation(TypeEfficacy
,
491 ==TypeEfficacy
.damage_type_id
,
492 backref
='damage_type')
493 Type
.target_efficacies
= relation(TypeEfficacy
,
495 ==TypeEfficacy
.target_type_id
,
496 backref
='target_type')
498 Version
.version_group
= relation(VersionGroup
, backref
='versions')
499 Version
.generation
= association_proxy('version_group', 'generation')
501 VersionGroup
.generation
= relation(Generation
, backref
='version_groups')