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 Machine(TableBase
):
166 __tablename__
= 'machines'
167 machine_number
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
168 generation_id
= Column(Integer
, ForeignKey('generations.id'), primary_key
=True, nullable
=False, autoincrement
=False)
169 move_id
= Column(Integer
, ForeignKey('moves.id'), nullable
=False)
171 class MoveDamageClass(TableBase
):
172 __tablename__
= 'move_damage_classes'
173 id = Column(Integer
, primary_key
=True, nullable
=False)
174 name
= Column(Unicode(8), nullable
=False)
175 description
= Column(Unicode(64), nullable
=False)
177 class MoveEffect(TableBase
):
178 __tablename__
= 'move_effects'
179 id = Column(Integer
, primary_key
=True, nullable
=False)
180 priority
= Column(SmallInteger
, nullable
=False)
181 short_effect
= Column(Unicode(256), nullable
=False)
182 effect
= Column(Unicode(5120), nullable
=False)
184 class MoveFlag(TableBase
):
185 __tablename__
= 'move_flags'
186 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
187 move_flag_type_id
= Column(Integer
, ForeignKey('move_flag_types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
189 class MoveFlagType(TableBase
):
190 __tablename__
= 'move_flag_types'
191 id = Column(Integer
, primary_key
=True, nullable
=False)
192 name
= Column(Unicode(32), nullable
=False)
193 description
= Column(rst
.RstTextColumn(128), nullable
=False)
195 class MoveName(TableBase
):
196 __tablename__
= 'move_names'
197 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
198 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
199 name
= Column(Unicode(16), nullable
=False)
201 class MoveTarget(TableBase
):
202 __tablename__
= 'move_targets'
203 id = Column(Integer
, primary_key
=True, nullable
=False)
204 name
= Column(Unicode(32), nullable
=False)
205 description
= Column(Unicode(128), nullable
=False)
207 class Move(TableBase
):
208 __tablename__
= 'moves'
209 __singlename__
= 'move'
210 id = Column(Integer
, primary_key
=True, nullable
=False)
211 name
= Column(Unicode(12), nullable
=False)
212 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
213 type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=False)
214 power
= Column(SmallInteger
)
215 pp
= Column(SmallInteger
, nullable
=False)
216 accuracy
= Column(SmallInteger
)
217 target_id
= Column(Integer
, ForeignKey('move_targets.id'), nullable
=False)
218 damage_class_id
= Column(Integer
, ForeignKey('move_damage_classes.id'), nullable
=False)
219 effect_id
= Column(Integer
, ForeignKey('move_effects.id'), nullable
=False)
220 effect_chance
= Column(Integer
)
221 contest_type
= Column(Unicode(8), nullable
=False)
222 contest_effect_id
= Column(Integer
, ForeignKey('contest_effects.id'), nullable
=True)
223 super_contest_effect_id
= Column(Integer
, nullable
=False)
225 class Pokemon(TableBase
):
226 """The core to this whole mess.
228 Note that I use both 'forme' and 'form' in both code and the database. I
229 only use 'forme' when specifically referring to Pokémon that have multiple
230 distinct species as forms—i.e., different stats or movesets. 'Form' is a
231 more general term referring to any variation within a species, including
232 purely cosmetic forms like Unown.
234 __tablename__
= 'pokemon'
235 __singlename__
= 'pokemon'
236 id = Column(Integer
, primary_key
=True, nullable
=False)
237 name
= Column(Unicode(20), nullable
=False)
238 forme_name
= Column(Unicode(16))
239 forme_base_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'))
240 generation_id
= Column(Integer
, ForeignKey('generations.id'))
241 evolution_chain_id
= Column(Integer
, ForeignKey('evolution_chains.id'))
242 evolution_parent_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'))
243 evolution_method_id
= Column(Integer
, ForeignKey('evolution_methods.id'))
244 evolution_parameter
= Column(Unicode(32))
245 height
= Column(Integer
, nullable
=False)
246 weight
= Column(Integer
, nullable
=False)
247 species
= Column(Unicode(16), nullable
=False)
248 color
= Column(Unicode(6), nullable
=False)
249 pokemon_shape_id
= Column(Integer
, ForeignKey('pokemon_shapes.id'), nullable
=False)
250 habitat
= Column(Unicode(16), nullable
=False)
251 gender_rate
= Column(Integer
, nullable
=False)
252 capture_rate
= Column(Integer
, nullable
=False)
253 base_experience
= Column(Integer
, nullable
=False)
254 base_happiness
= Column(Integer
, nullable
=False)
255 gen1_internal_id
= Column(Integer
)
256 is_baby
= Column(Boolean
, nullable
=False)
257 has_gen4_fem_sprite
= Column(Boolean
, nullable
=False)
258 has_gen4_fem_back_sprite
= Column(Boolean
, nullable
=False)
260 ### Stuff to handle alternate Pokémon forms
263 def national_id(self
):
264 """Returns the National Pokédex number for this Pokémon. Use this
265 instead of the id directly; alternate formes may make the id incorrect.
268 if self
.forme_base_pokemon_id
:
269 return self
.forme_base_pokemon_id
274 """Returns the name of this Pokémon, including its Forme, if any."""
277 return "%s %s" %
(self
.forme_name
.capitalize(), self
.name
)
281 def normal_form(self
):
282 """Returns the normal form for this Pokémon; i.e., this will return
283 regular Deoxys when called on any Deoxys form.
286 if self
.forme_base_pokemon
:
287 return self
.forme_base_pokemon
291 class PokemonAbility(TableBase
):
292 __tablename__
= 'pokemon_abilities'
293 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
294 ability_id
= Column(Integer
, ForeignKey('abilities.id'), nullable
=False)
295 slot
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
297 class PokemonDexNumber(TableBase
):
298 __tablename__
= 'pokemon_dex_numbers'
299 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
300 generation_id
= Column(Integer
, ForeignKey('generations.id'), primary_key
=True, nullable
=False, autoincrement
=False)
301 pokedex_number
= Column(Integer
, nullable
=False)
303 class PokemonEggGroup(TableBase
):
304 __tablename__
= 'pokemon_egg_groups'
305 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
306 egg_group_id
= Column(Integer
, ForeignKey('egg_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
308 class PokemonFlavorText(TableBase
):
309 __tablename__
= 'pokemon_flavor_text'
310 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
311 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
312 flavor_text
= Column(Unicode(255), nullable
=False)
314 class PokemonFormGroup(TableBase
):
315 __tablename__
= 'pokemon_form_groups'
316 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
317 description
= Column(Unicode(512), nullable
=False)
319 class PokemonFormSprite(TableBase
):
320 __tablename__
= 'pokemon_form_sprites'
321 id = Column(Integer
, primary_key
=True, nullable
=False)
322 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
323 name
= Column(Unicode(16), nullable
=True)
325 class PokemonItem(TableBase
):
326 __tablename__
= 'pokemon_items'
327 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
328 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
329 item_id
= Column(Integer
, ForeignKey('items.id'), primary_key
=True, nullable
=False, autoincrement
=False)
330 rarity
= Column(Integer
, nullable
=False)
332 class PokemonMove(TableBase
):
333 __tablename__
= 'pokemon_moves'
334 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
335 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
336 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False, index
=True)
337 pokemon_move_method_id
= Column(Integer
, ForeignKey('pokemon_move_methods.id'), primary_key
=True, nullable
=False, autoincrement
=False)
338 level
= Column(Integer
, primary_key
=True, nullable
=True, autoincrement
=False)
339 order
= Column(Integer
, nullable
=True)
341 class PokemonMoveMethod(TableBase
):
342 __tablename__
= 'pokemon_move_methods'
343 id = Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
344 name
= Column(Unicode(64), nullable
=False)
345 description
= Column(Unicode(255), nullable
=False)
347 class PokemonName(TableBase
):
348 __tablename__
= 'pokemon_names'
349 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
350 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
351 name
= Column(Unicode(16), nullable
=False)
353 class PokemonShape(TableBase
):
354 __tablename__
= 'pokemon_shapes'
355 id = Column(Integer
, primary_key
=True, nullable
=False)
356 name
= Column(Unicode(24), nullable
=False)
357 awesome_name
= Column(Unicode(16), nullable
=False)
359 class PokemonStat(TableBase
):
360 __tablename__
= 'pokemon_stats'
361 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
362 stat_id
= Column(Integer
, ForeignKey('stats.id'), primary_key
=True, nullable
=False, autoincrement
=False)
363 base_stat
= Column(Integer
, nullable
=False)
364 effort
= Column(Integer
, nullable
=False)
366 class PokemonType(TableBase
):
367 __tablename__
= 'pokemon_types'
368 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
369 type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=False)
370 slot
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
372 class Stat(TableBase
):
373 __tablename__
= 'stats'
374 id = Column(Integer
, primary_key
=True, nullable
=False)
375 name
= Column(Unicode(16), nullable
=False)
377 class TypeEfficacy(TableBase
):
378 __tablename__
= 'type_efficacy'
379 damage_type_id
= Column(Integer
, ForeignKey('types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
380 target_type_id
= Column(Integer
, ForeignKey('types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
381 damage_factor
= Column(Integer
, nullable
=False)
383 class Type(TableBase
):
384 __tablename__
= 'types'
385 __singlename__
= 'type'
386 id = Column(Integer
, primary_key
=True, nullable
=False)
387 name
= Column(Unicode(8), nullable
=False)
388 abbreviation
= Column(Unicode(3), nullable
=False)
390 class VersionGroup(TableBase
):
391 __tablename__
= 'version_groups'
392 id = Column(Integer
, primary_key
=True, nullable
=False)
393 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
395 class Version(TableBase
):
396 __tablename__
= 'versions'
397 id = Column(Integer
, primary_key
=True, nullable
=False)
398 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), nullable
=False)
399 name
= Column(Unicode(32), nullable
=False)
402 ### Relations down here, to avoid ordering problems
403 Encounter
.pokemon
= relation(Pokemon
, backref
='encounters')
404 Encounter
.version
= relation(Version
, backref
='encounters')
405 Encounter
.location_area
= relation(LocationArea
, backref
='encounters')
406 Encounter
.slot
= relation(EncounterTypeSlot
, backref
='encounters')
407 Encounter
.condition
= relation(EncounterCondition
, backref
='encounters')
409 EncounterCondition
.group
= relation(EncounterConditionGroup
,
410 backref
='conditions')
412 EncounterTypeSlot
.type = relation(EncounterType
, backref
='slots')
414 EvolutionChain
.growth_rate
= relation(GrowthRate
, backref
='evolution_chains')
416 Generation
.versions
= relation(Version
, secondary
=VersionGroup
.__table__
)
418 LocationArea
.location
= relation(Location
, backref
='areas')
420 Machine
.generation
= relation(Generation
)
422 Move
.damage_class
= relation(MoveDamageClass
, backref
='moves')
423 Move
.flags
= association_proxy('move_flags', 'flag')
424 Move
.foreign_names
= relation(MoveName
, backref
='pokemon')
425 Move
.generation
= relation(Generation
, backref
='moves')
426 Move
.machines
= relation(Machine
, backref
='move')
427 Move
.move_effect
= relation(MoveEffect
, backref
='moves')
428 Move
.move_flags
= relation(MoveFlag
, backref
='move')
429 Move
.target
= relation(MoveTarget
, backref
='moves')
430 Move
.type = relation(Type
, backref
='moves')
432 Move
.effect
= rst
.MoveEffectProperty('effect')
433 Move
.priority
= association_proxy('move_effect', 'priority')
434 Move
.short_effect
= rst
.MoveEffectProperty('short_effect')
436 MoveFlag
.flag
= relation(MoveFlagType
)
438 MoveName
.language
= relation(Language
)
440 Pokemon
.abilities
= relation(Ability
, secondary
=PokemonAbility
.__table__
,
441 order_by
=PokemonAbility
.slot
,
443 Pokemon
.formes
= relation(Pokemon
, primaryjoin
=Pokemon
.id==Pokemon
.forme_base_pokemon_id
,
444 backref
=backref('forme_base_pokemon',
445 remote_side
=[Pokemon
.id]))
446 Pokemon
.dex_numbers
= relation(PokemonDexNumber
, backref
='pokemon')
447 Pokemon
.egg_groups
= relation(EggGroup
, secondary
=PokemonEggGroup
.__table__
,
448 order_by
=PokemonEggGroup
.egg_group_id
,
450 Pokemon
.evolution_chain
= relation(EvolutionChain
, backref
='pokemon')
451 Pokemon
.evolution_method
= relation(EvolutionMethod
)
452 Pokemon
.evolution_children
= relation(Pokemon
, primaryjoin
=Pokemon
.id==Pokemon
.evolution_parent_pokemon_id
,
453 backref
=backref('evolution_parent',
454 remote_side
=[Pokemon
.id]))
455 Pokemon
.flavor_text
= relation(PokemonFlavorText
, backref
='pokemon')
456 Pokemon
.foreign_names
= relation(PokemonName
, backref
='pokemon')
457 Pokemon
.items
= relation(PokemonItem
)
458 Pokemon
.generation
= relation(Generation
, backref
='pokemon')
459 Pokemon
.shape
= relation(PokemonShape
, backref
='pokemon')
460 Pokemon
.stats
= relation(PokemonStat
, backref
='pokemon')
461 Pokemon
.types
= relation(Type
, secondary
=PokemonType
.__table__
)
463 PokemonDexNumber
.generation
= relation(Generation
)
465 PokemonFlavorText
.version
= relation(Version
)
467 PokemonItem
.item
= relation(Item
, backref
='pokemon')
468 PokemonItem
.version
= relation(Version
)
470 PokemonFormGroup
.pokemon
= relation(Pokemon
, backref
=backref('form_group',
472 PokemonFormSprite
.pokemon
= relation(Pokemon
, backref
='form_sprites')
474 PokemonMove
.pokemon
= relation(Pokemon
, backref
='pokemon_moves')
475 PokemonMove
.version_group
= relation(VersionGroup
)
476 PokemonMove
.move
= relation(Move
, backref
='pokemon_moves')
477 PokemonMove
.method
= relation(PokemonMoveMethod
)
479 PokemonName
.language
= relation(Language
)
481 PokemonStat
.stat
= relation(Stat
)
483 Type
.damage_efficacies
= relation(TypeEfficacy
,
485 ==TypeEfficacy
.damage_type_id
,
486 backref
='damage_type')
487 Type
.target_efficacies
= relation(TypeEfficacy
,
489 ==TypeEfficacy
.target_type_id
,
490 backref
='target_type')
492 Version
.version_group
= relation(VersionGroup
, backref
='versions')
493 Version
.generation
= association_proxy('version_group', 'generation')
495 VersionGroup
.generation
= relation(Generation
, backref
='version_groups')