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
, eagerload_all
, relation
7 from sqlalchemy
.orm
.session
import Session
8 from sqlalchemy
.sql
import and_
9 from sqlalchemy
.types
import *
11 from pokedex
.db
import markdown
14 TableBase
= declarative_base(metadata
=metadata
)
16 class Ability(TableBase
):
17 __tablename__
= 'abilities'
18 __singlename__
= 'ability'
19 id = Column(Integer
, primary_key
=True, nullable
=False)
20 name
= Column(Unicode(24), nullable
=False)
21 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
22 effect
= Column(markdown
.MarkdownColumn(5120), nullable
=False)
23 short_effect
= Column(markdown
.MarkdownColumn(255), nullable
=False)
25 class AbilityFlavorText(TableBase
):
26 __tablename__
= 'ability_flavor_text'
27 ability_id
= Column(Integer
, ForeignKey('abilities.id'), primary_key
=True, nullable
=False, autoincrement
=False)
28 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
29 flavor_text
= Column(Unicode(64), nullable
=False)
31 class AbilityName(TableBase
):
32 __tablename__
= 'ability_names'
33 ability_id
= Column(Integer
, ForeignKey('abilities.id'), primary_key
=True, nullable
=False, autoincrement
=False)
34 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
35 name
= Column(Unicode(16), nullable
=False)
37 class Berry(TableBase
):
38 __tablename__
= 'berries'
39 id = Column(Integer
, primary_key
=True, nullable
=False)
40 item_id
= Column(Integer
, ForeignKey('items.id'), nullable
=False)
41 firmness_id
= Column(Integer
, ForeignKey('berry_firmness.id'), nullable
=False)
42 natural_gift_power
= Column(Integer
, nullable
=True)
43 natural_gift_type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=True)
44 size
= Column(Integer
, nullable
=False)
45 max_harvest
= Column(Integer
, nullable
=False)
46 growth_time
= Column(Integer
, nullable
=False)
47 soil_dryness
= Column(Integer
, nullable
=False)
48 smoothness
= Column(Integer
, nullable
=False)
50 class BerryFirmness(TableBase
):
51 __tablename__
= 'berry_firmness'
52 id = Column(Integer
, primary_key
=True, nullable
=False)
53 name
= Column(Unicode(10), nullable
=False)
55 class BerryFlavor(TableBase
):
56 __tablename__
= 'berry_flavors'
57 berry_id
= Column(Integer
, ForeignKey('berries.id'), primary_key
=True, nullable
=False, autoincrement
=False)
58 contest_type_id
= Column(Integer
, ForeignKey('contest_types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
59 flavor
= Column(Integer
, nullable
=False)
61 class ContestCombo(TableBase
):
62 __tablename__
= 'contest_combos'
63 first_move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
64 second_move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
66 class ContestEffect(TableBase
):
67 __tablename__
= 'contest_effects'
68 id = Column(Integer
, primary_key
=True, nullable
=False)
69 appeal
= Column(SmallInteger
, nullable
=False)
70 jam
= Column(SmallInteger
, nullable
=False)
71 flavor_text
= Column(Unicode(64), nullable
=False)
72 effect
= Column(Unicode(255), nullable
=False)
74 class ContestType(TableBase
):
75 __tablename__
= 'contest_types'
76 id = Column(Integer
, primary_key
=True, nullable
=False)
77 name
= Column(Unicode(6), nullable
=False)
78 flavor
= Column(Unicode(6), nullable
=False)
79 color
= Column(Unicode(6), nullable
=False)
81 class EggGroup(TableBase
):
82 __tablename__
= 'egg_groups'
83 id = Column(Integer
, primary_key
=True, nullable
=False)
84 name
= Column(Unicode(16), nullable
=False)
86 class Encounter(TableBase
):
87 """Rows in this table represent encounters with wild Pokémon. Bear with
90 Within a given area in a given game, encounters are differentiated by the
91 "slot" they are in and the state of the game world.
93 What the player is doing to get an encounter, such as surfing or walking
94 through tall grass, is called terrain. Each terrain has its own set of
97 Within a terrain, slots are defined primarily by rarity. Each slot can
98 also be affected by world conditions; for example, the 20% slot for walking
99 in tall grass is affected by whether a swarm is in effect in that area.
100 "Is there a swarm?" is a condition; "there is a swarm" and "there is not a
101 swarm" are the possible values of this condition.
103 A slot (20% walking in grass) and any appropriate world conditions (no
104 swarm) are thus enough to define a specific encounter.
106 Well, okay, almost: each slot actually appears twice.
109 __tablename__
= 'encounters'
110 id = Column(Integer
, primary_key
=True, nullable
=False)
111 version_id
= Column(Integer
, ForeignKey('versions.id'), nullable
=False, autoincrement
=False)
112 location_area_id
= Column(Integer
, ForeignKey('location_areas.id'), nullable
=False, autoincrement
=False)
113 encounter_slot_id
= Column(Integer
, ForeignKey('encounter_slots.id'), nullable
=False, autoincrement
=False)
114 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), nullable
=False, autoincrement
=False)
115 min_level
= Column(Integer
, nullable
=False, autoincrement
=False)
116 max_level
= Column(Integer
, nullable
=False, autoincrement
=False)
118 class EncounterCondition(TableBase
):
119 """Rows in this table represent varying conditions in the game world, such
123 __tablename__
= 'encounter_conditions'
124 id = Column(Integer
, primary_key
=True, nullable
=False)
125 name
= Column(Unicode(64), nullable
=False)
127 class EncounterConditionValue(TableBase
):
128 """Rows in this table represent possible states for a condition; for
129 example, the state of 'swarm' could be 'swarm' or 'no swarm'.
132 __tablename__
= 'encounter_condition_values'
133 id = Column(Integer
, primary_key
=True, nullable
=False)
134 encounter_condition_id
= Column(Integer
, ForeignKey('encounter_conditions.id'), primary_key
=False, nullable
=False, autoincrement
=False)
135 name
= Column(Unicode(64), nullable
=False)
136 is_default
= Column(Boolean
, nullable
=False)
138 class EncounterConditionValueMap(TableBase
):
139 """Maps encounters to the specific conditions under which they occur."""
141 __tablename__
= 'encounter_condition_value_map'
142 encounter_id
= Column(Integer
, ForeignKey('encounters.id'), primary_key
=True, nullable
=False, autoincrement
=False)
143 encounter_condition_value_id
= Column(Integer
, ForeignKey('encounter_condition_values.id'), primary_key
=True, nullable
=False, autoincrement
=False)
145 class EncounterTerrain(TableBase
):
146 """Rows in this table represent ways the player can enter a wild encounter,
147 e.g., surfing, fishing, or walking through tall grass.
150 __tablename__
= 'encounter_terrain'
151 id = Column(Integer
, primary_key
=True, nullable
=False)
152 name
= Column(Unicode(64), nullable
=False)
154 class EncounterSlot(TableBase
):
155 """Rows in this table represent an abstract "slot" within a terrain,
156 associated with both some set of conditions and a rarity.
158 Note that there are two encounters per slot, so the rarities will only add
162 __tablename__
= 'encounter_slots'
163 id = Column(Integer
, primary_key
=True, nullable
=False)
164 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), nullable
=False, autoincrement
=False)
165 encounter_terrain_id
= Column(Integer
, ForeignKey('encounter_terrain.id'), primary_key
=False, nullable
=False, autoincrement
=False)
166 slot
= Column(Integer
, nullable
=True)
167 rarity
= Column(Integer
, nullable
=False)
169 class EncounterSlotCondition(TableBase
):
170 """Lists all conditions that affect each slot."""
172 __tablename__
= 'encounter_slot_conditions'
173 encounter_slot_id
= Column(Integer
, ForeignKey('encounter_slots.id'), primary_key
=True, nullable
=False, autoincrement
=False)
174 encounter_condition_id
= Column(Integer
, ForeignKey('encounter_conditions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
176 class EvolutionChain(TableBase
):
177 __tablename__
= 'evolution_chains'
178 id = Column(Integer
, primary_key
=True, nullable
=False)
179 growth_rate_id
= Column(Integer
, ForeignKey('growth_rates.id'), nullable
=False)
180 steps_to_hatch
= Column(Integer
, nullable
=False)
181 baby_trigger_item
= Column(Unicode(12))
183 class EvolutionTrigger(TableBase
):
184 __tablename__
= 'evolution_triggers'
185 id = Column(Integer
, primary_key
=True, nullable
=False)
186 identifier
= Column(Unicode(16), nullable
=False)
188 class Experience(TableBase
):
189 __tablename__
= 'experience'
190 growth_rate_id
= Column(Integer
, ForeignKey('growth_rates.id'), primary_key
=True, nullable
=False)
191 level
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
192 experience
= Column(Integer
, nullable
=False)
194 class Generation(TableBase
):
195 __tablename__
= 'generations'
196 id = Column(Integer
, primary_key
=True, nullable
=False)
197 main_region_id
= Column(Integer
, ForeignKey('regions.id'))
198 canonical_pokedex_id
= Column(Integer
, ForeignKey('pokedexes.id'))
199 name
= Column(Unicode(16), nullable
=False)
201 class GrowthRate(TableBase
):
202 """`formula` is written in LaTeX math notation."""
203 __tablename__
= 'growth_rates'
204 id = Column(Integer
, primary_key
=True, nullable
=False)
205 name
= Column(Unicode(20), nullable
=False)
206 formula
= Column(Unicode(500), nullable
=False)
208 class Item(TableBase
):
209 __tablename__
= 'items'
210 __singlename__
= 'item'
211 id = Column(Integer
, primary_key
=True, nullable
=False)
212 name
= Column(Unicode(16), nullable
=False)
213 category_id
= Column(Integer
, ForeignKey('item_categories.id'), nullable
=False)
214 cost
= Column(Integer
, nullable
=False)
215 fling_power
= Column(Integer
, nullable
=True)
216 fling_effect_id
= Column(Integer
, ForeignKey('item_fling_effects.id'), nullable
=True)
217 effect
= Column(markdown
.MarkdownColumn(5120), nullable
=False)
220 def appears_underground(self
):
221 return any(flag
.identifier
== u
'underground' for flag
in self
.flags
)
223 class ItemCategory(TableBase
):
224 __tablename__
= 'item_categories'
225 id = Column(Integer
, primary_key
=True, nullable
=False)
226 pocket_id
= Column(Integer
, ForeignKey('item_pockets.id'), nullable
=False)
227 name
= Column(Unicode(16), nullable
=False)
229 class ItemFlag(TableBase
):
230 __tablename__
= 'item_flags'
231 id = Column(Integer
, primary_key
=True, nullable
=False)
232 identifier
= Column(Unicode(24), nullable
=False)
233 name
= Column(Unicode(64), nullable
=False)
235 class ItemFlagMap(TableBase
):
236 __tablename__
= 'item_flag_map'
237 item_id
= Column(Integer
, ForeignKey('items.id'), primary_key
=True, autoincrement
=False, nullable
=False)
238 item_flag_id
= Column(Integer
, ForeignKey('item_flags.id'), primary_key
=True, autoincrement
=False, nullable
=False)
240 class ItemFlavorText(TableBase
):
241 __tablename__
= 'item_flavor_text'
242 item_id
= Column(Integer
, ForeignKey('items.id'), primary_key
=True, autoincrement
=False, nullable
=False)
243 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, autoincrement
=False, nullable
=False)
244 flavor_text
= Column(Unicode(255), nullable
=False)
246 class ItemFlingEffect(TableBase
):
247 __tablename__
= 'item_fling_effects'
248 id = Column(Integer
, primary_key
=True, nullable
=False)
249 effect
= Column(Unicode(255), nullable
=False)
251 class ItemInternalID(TableBase
):
252 __tablename__
= 'item_internal_ids'
253 item_id
= Column(Integer
, ForeignKey('items.id'), primary_key
=True, autoincrement
=False, nullable
=False)
254 generation_id
= Column(Integer
, ForeignKey('generations.id'), primary_key
=True, autoincrement
=False, nullable
=False)
255 internal_id
= Column(Integer
, nullable
=False)
257 class ItemPocket(TableBase
):
258 __tablename__
= 'item_pockets'
259 id = Column(Integer
, primary_key
=True, nullable
=False)
260 identifier
= Column(Unicode(16), nullable
=False)
261 name
= Column(Unicode(16), nullable
=False)
263 class Language(TableBase
):
264 __tablename__
= 'languages'
265 id = Column(Integer
, primary_key
=True, nullable
=False)
266 iso639
= Column(Unicode(2), nullable
=False)
267 iso3166
= Column(Unicode(2), nullable
=False)
268 name
= Column(Unicode(16), nullable
=False)
270 class Location(TableBase
):
271 __tablename__
= 'locations'
272 __singlename__
= 'location'
273 id = Column(Integer
, primary_key
=True, nullable
=False)
274 region_id
= Column(Integer
, ForeignKey('regions.id'))
275 name
= Column(Unicode(64), nullable
=False)
277 class LocationArea(TableBase
):
278 __tablename__
= 'location_areas'
279 id = Column(Integer
, primary_key
=True, nullable
=False)
280 location_id
= Column(Integer
, ForeignKey('locations.id'), nullable
=False)
281 internal_id
= Column(Integer
, nullable
=False)
282 name
= Column(Unicode(64), nullable
=True)
284 class LocationAreaEncounterRate(TableBase
):
285 __tablename__
= 'location_area_encounter_rates'
286 location_area_id
= Column(Integer
, ForeignKey('location_areas.id'), primary_key
=True, nullable
=False, autoincrement
=False)
287 encounter_terrain_id
= Column(Integer
, ForeignKey('encounter_terrain.id'), primary_key
=True, nullable
=False, autoincrement
=False)
288 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, autoincrement
=False)
289 rate
= Column(Integer
, nullable
=True)
291 class Machine(TableBase
):
292 __tablename__
= 'machines'
293 machine_number
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
294 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
295 item_id
= Column(Integer
, ForeignKey('items.id'), nullable
=False)
296 move_id
= Column(Integer
, ForeignKey('moves.id'), nullable
=False)
300 return self
.machine_number
>= 100
302 class MoveBattleStyle(TableBase
):
303 __tablename__
= 'move_battle_styles'
304 id = Column(Integer
, primary_key
=True, nullable
=False)
305 name
= Column(Unicode(8), nullable
=False)
307 class MoveEffectCategory(TableBase
):
308 __tablename__
= 'move_effect_categories'
309 id = Column(Integer
, primary_key
=True, nullable
=False)
310 name
= Column(Unicode(64), nullable
=False)
311 can_affect_user
= Column(Boolean
, nullable
=False)
313 class MoveEffectCategoryMap(TableBase
):
314 __tablename__
= 'move_effect_category_map'
315 move_effect_id
= Column(Integer
, ForeignKey('move_effects.id'), primary_key
=True, nullable
=False)
316 move_effect_category_id
= Column(Integer
, ForeignKey('move_effect_categories.id'), primary_key
=True, nullable
=False)
317 affects_user
= Column(Boolean
, primary_key
=True, nullable
=False)
319 class MoveDamageClass(TableBase
):
320 __tablename__
= 'move_damage_classes'
321 id = Column(Integer
, primary_key
=True, nullable
=False)
322 name
= Column(Unicode(8), nullable
=False)
323 description
= Column(Unicode(64), nullable
=False)
325 class MoveEffect(TableBase
):
326 __tablename__
= 'move_effects'
327 id = Column(Integer
, primary_key
=True, nullable
=False)
328 priority
= Column(SmallInteger
, nullable
=False)
329 short_effect
= Column(Unicode(256), nullable
=False)
330 effect
= Column(Unicode(5120), nullable
=False)
332 class MoveFlag(TableBase
):
333 __tablename__
= 'move_flags'
334 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
335 move_flag_type_id
= Column(Integer
, ForeignKey('move_flag_types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
337 class MoveFlagType(TableBase
):
338 __tablename__
= 'move_flag_types'
339 id = Column(Integer
, primary_key
=True, nullable
=False)
340 name
= Column(Unicode(32), nullable
=False)
341 description
= Column(markdown
.MarkdownColumn(128), nullable
=False)
343 class MoveFlavorText(TableBase
):
344 __tablename__
= 'move_flavor_text'
345 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
346 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
347 flavor_text
= Column(Unicode(255), nullable
=False)
349 class MoveName(TableBase
):
350 __tablename__
= 'move_names'
351 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
352 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
353 name
= Column(Unicode(16), nullable
=False)
355 class MoveTarget(TableBase
):
356 __tablename__
= 'move_targets'
357 id = Column(Integer
, primary_key
=True, nullable
=False)
358 name
= Column(Unicode(32), nullable
=False)
359 description
= Column(Unicode(128), nullable
=False)
361 class Move(TableBase
):
362 __tablename__
= 'moves'
363 __singlename__
= 'move'
364 id = Column(Integer
, primary_key
=True, nullable
=False)
365 name
= Column(Unicode(12), nullable
=False)
366 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
367 type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=False)
368 power
= Column(SmallInteger
)
369 pp
= Column(SmallInteger
, nullable
=False)
370 accuracy
= Column(SmallInteger
)
371 target_id
= Column(Integer
, ForeignKey('move_targets.id'), nullable
=False)
372 damage_class_id
= Column(Integer
, ForeignKey('move_damage_classes.id'), nullable
=False)
373 effect_id
= Column(Integer
, ForeignKey('move_effects.id'), nullable
=False)
374 effect_chance
= Column(Integer
)
375 contest_type_id
= Column(Integer
, ForeignKey('contest_types.id'), nullable
=True)
376 contest_effect_id
= Column(Integer
, ForeignKey('contest_effects.id'), nullable
=True)
377 super_contest_effect_id
= Column(Integer
, ForeignKey('super_contest_effects.id'), nullable
=False)
379 class Nature(TableBase
):
380 __tablename__
= 'natures'
381 __singlename__
= 'nature'
382 id = Column(Integer
, primary_key
=True, nullable
=False)
383 name
= Column(Unicode(8), nullable
=False)
384 decreased_stat_id
= Column(Integer
, ForeignKey('stats.id'), nullable
=False)
385 increased_stat_id
= Column(Integer
, ForeignKey('stats.id'), nullable
=False)
386 hates_flavor_id
= Column(Integer
, ForeignKey('contest_types.id'), nullable
=False)
387 likes_flavor_id
= Column(Integer
, ForeignKey('contest_types.id'), nullable
=False)
389 class NatureBattleStylePreference(TableBase
):
390 __tablename__
= 'nature_battle_style_preferences'
391 nature_id
= Column(Integer
, ForeignKey('natures.id'), primary_key
=True, nullable
=False)
392 move_battle_style_id
= Column(Integer
, ForeignKey('move_battle_styles.id'), primary_key
=True, nullable
=False)
393 low_hp_preference
= Column(Integer
, nullable
=False)
394 high_hp_preference
= Column(Integer
, nullable
=False)
396 class NatureName(TableBase
):
397 __tablename__
= 'nature_names'
398 nature_id
= Column(Integer
, ForeignKey('natures.id'), primary_key
=True, nullable
=False, autoincrement
=False)
399 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
400 name
= Column(Unicode(8), nullable
=False)
402 class NaturePokeathlonStat(TableBase
):
403 __tablename__
= 'nature_pokeathlon_stats'
404 nature_id
= Column(Integer
, ForeignKey('natures.id'), primary_key
=True, nullable
=False)
405 pokeathlon_stat_id
= Column(Integer
, ForeignKey('pokeathlon_stats.id'), primary_key
=True, nullable
=False)
406 max_change
= Column(Integer
, nullable
=False)
408 class PokeathlonStat(TableBase
):
409 __tablename__
= 'pokeathlon_stats'
410 id = Column(Integer
, primary_key
=True, nullable
=False)
411 name
= Column(Unicode(8), nullable
=False)
413 class Pokedex(TableBase
):
414 __tablename__
= 'pokedexes'
415 id = Column(Integer
, primary_key
=True, nullable
=False)
416 region_id
= Column(Integer
, ForeignKey('regions.id'), nullable
=True)
417 name
= Column(Unicode(16), nullable
=False)
418 description
= Column(Unicode(512))
420 class PokedexVersionGroup(TableBase
):
421 __tablename__
= 'pokedex_version_groups'
422 pokedex_id
= Column(Integer
, ForeignKey('pokedexes.id'), primary_key
=True, nullable
=False, autoincrement
=False)
423 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
425 class Pokemon(TableBase
):
426 """The core to this whole mess.
428 Note that I use both 'forme' and 'form' in both code and the database. I
429 only use 'forme' when specifically referring to Pokémon that have multiple
430 distinct species as forms—i.e., different stats or movesets. 'Form' is a
431 more general term referring to any variation within a species, including
432 purely cosmetic forms like Unown.
434 __tablename__
= 'pokemon'
435 __singlename__
= 'pokemon'
436 id = Column(Integer
, primary_key
=True, nullable
=False)
437 name
= Column(Unicode(20), nullable
=False)
438 forme_name
= Column(Unicode(16))
439 forme_base_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'))
440 generation_id
= Column(Integer
, ForeignKey('generations.id'))
441 evolution_chain_id
= Column(Integer
, ForeignKey('evolution_chains.id'))
442 height
= Column(Integer
, nullable
=False)
443 weight
= Column(Integer
, nullable
=False)
444 species
= Column(Unicode(16), nullable
=False)
445 color_id
= Column(Integer
, ForeignKey('pokemon_colors.id'), nullable
=False)
446 pokemon_shape_id
= Column(Integer
, ForeignKey('pokemon_shapes.id'), nullable
=False)
447 habitat_id
= Column(Integer
, ForeignKey('pokemon_habitats.id'), nullable
=True)
448 gender_rate
= Column(Integer
, nullable
=False)
449 capture_rate
= Column(Integer
, nullable
=False)
450 base_experience
= Column(Integer
, nullable
=False)
451 base_happiness
= Column(Integer
, nullable
=False)
452 is_baby
= Column(Boolean
, nullable
=False)
453 has_gen4_fem_sprite
= Column(Boolean
, nullable
=False)
454 has_gen4_fem_back_sprite
= Column(Boolean
, nullable
=False)
456 ### Stuff to handle alternate Pokémon forms
459 def national_id(self
):
460 """Returns the National Pokédex number for this Pokémon. Use this
461 instead of the id directly; alternate formes may make the id incorrect.
464 if self
.forme_base_pokemon_id
:
465 return self
.forme_base_pokemon_id
470 """Returns the name of this Pokémon, including its Forme, if any."""
473 return "%s %s" %
(self
.forme_name
.title(), self
.name
)
477 def normal_form(self
):
478 """Returns the normal form for this Pokémon; i.e., this will return
479 regular Deoxys when called on any Deoxys form.
482 if self
.forme_base_pokemon
:
483 return self
.forme_base_pokemon
489 def stat(self
, stat_name
):
490 """Returns a PokemonStat record for the given stat name (or Stat row
491 object). Uses the normal has-many machinery, so all the stats are
494 if isinstance(stat_name
, Stat
):
495 stat_name
= stat_name
.name
497 for pokemon_stat
in self
.stats
:
498 if pokemon_stat
.stat
.name
== stat_name
:
501 raise KeyError(u
'No stat named %s' % stat_name
)
504 def better_damage_class(self
):
505 u
"""Returns the MoveDamageClass that this Pokémon is best suited for,
506 based on its attack stats.
508 If the attack stats are about equal (within 5), returns None. The
509 value None, not the damage class called 'None'.
511 phys
= self
.stat(u
'Attack')
512 spec
= self
.stat(u
'Special Attack')
514 diff
= phys
.base_stat
- spec
.base_stat
517 return phys
.stat
.damage_class
519 return spec
.stat
.damage_class
523 class PokemonAbility(TableBase
):
524 __tablename__
= 'pokemon_abilities'
525 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
526 ability_id
= Column(Integer
, ForeignKey('abilities.id'), nullable
=False)
527 slot
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
529 class PokemonColor(TableBase
):
530 __tablename__
= 'pokemon_colors'
531 id = Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
532 name
= Column(Unicode(6), nullable
=False)
534 class PokemonDexNumber(TableBase
):
535 __tablename__
= 'pokemon_dex_numbers'
536 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
537 pokedex_id
= Column(Integer
, ForeignKey('pokedexes.id'), primary_key
=True, nullable
=False, autoincrement
=False)
538 pokedex_number
= Column(Integer
, nullable
=False)
540 class PokemonEggGroup(TableBase
):
541 __tablename__
= 'pokemon_egg_groups'
542 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
543 egg_group_id
= Column(Integer
, ForeignKey('egg_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
545 class PokemonEvolution(TableBase
):
546 __tablename__
= 'pokemon_evolution'
547 from_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), nullable
=False)
548 to_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
549 evolution_trigger_id
= Column(Integer
, ForeignKey('evolution_triggers.id'), nullable
=False)
550 trigger_item_id
= Column(Integer
, ForeignKey('items.id'), nullable
=True)
551 minimum_level
= Column(Integer
, nullable
=True)
552 gender
= Column(Enum('male', 'female', name
='pokemon_evolution_gender'), nullable
=True)
553 location_id
= Column(Integer
, ForeignKey('locations.id'), nullable
=True)
554 held_item_id
= Column(Integer
, ForeignKey('items.id'), nullable
=True)
555 time_of_day
= Column(Enum('morning', 'day', 'night', name
='pokemon_evolution_time_of_day'), nullable
=True)
556 known_move_id
= Column(Integer
, ForeignKey('moves.id'), nullable
=True)
557 minimum_happiness
= Column(Integer
, nullable
=True)
558 minimum_beauty
= Column(Integer
, nullable
=True)
559 relative_physical_stats
= Column(Integer
, nullable
=True)
560 party_pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), nullable
=True)
562 class PokemonFlavorText(TableBase
):
563 __tablename__
= 'pokemon_flavor_text'
564 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
565 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
566 flavor_text
= Column(Unicode(255), nullable
=False)
568 class PokemonFormGroup(TableBase
):
569 __tablename__
= 'pokemon_form_groups'
570 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
571 is_battle_only
= Column(Boolean
, nullable
=False)
572 description
= Column(markdown
.MarkdownColumn(1024), nullable
=False)
574 class PokemonFormSprite(TableBase
):
575 __tablename__
= 'pokemon_form_sprites'
576 id = Column(Integer
, primary_key
=True, nullable
=False)
577 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
578 introduced_in_version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
579 name
= Column(Unicode(16), nullable
=True)
580 is_default
= Column(Boolean
, nullable
=True)
582 class PokemonHabitat(TableBase
):
583 __tablename__
= 'pokemon_habitats'
584 id = Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
585 name
= Column(Unicode(16), nullable
=False)
587 class PokemonInternalID(TableBase
):
588 __tablename__
= 'pokemon_internal_ids'
589 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, autoincrement
=False, nullable
=False)
590 generation_id
= Column(Integer
, ForeignKey('generations.id'), primary_key
=True, autoincrement
=False, nullable
=False)
591 internal_id
= Column(Integer
, nullable
=False)
593 class PokemonItem(TableBase
):
594 __tablename__
= 'pokemon_items'
595 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
596 version_id
= Column(Integer
, ForeignKey('versions.id'), primary_key
=True, nullable
=False, autoincrement
=False)
597 item_id
= Column(Integer
, ForeignKey('items.id'), primary_key
=True, nullable
=False, autoincrement
=False)
598 rarity
= Column(Integer
, nullable
=False)
600 class PokemonMove(TableBase
):
601 __tablename__
= 'pokemon_moves'
602 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
603 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False, autoincrement
=False)
604 move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False, index
=True)
605 pokemon_move_method_id
= Column(Integer
, ForeignKey('pokemon_move_methods.id'), primary_key
=True, nullable
=False, autoincrement
=False)
606 level
= Column(Integer
, primary_key
=True, nullable
=True, autoincrement
=False, index
=True)
607 order
= Column(Integer
, nullable
=True, index
=True)
609 class PokemonMoveMethod(TableBase
):
610 __tablename__
= 'pokemon_move_methods'
611 id = Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
612 name
= Column(Unicode(64), nullable
=False)
613 description
= Column(Unicode(255), nullable
=False)
615 class PokemonName(TableBase
):
616 __tablename__
= 'pokemon_names'
617 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
618 language_id
= Column(Integer
, ForeignKey('languages.id'), primary_key
=True, nullable
=False, autoincrement
=False)
619 name
= Column(Unicode(16), nullable
=False)
621 class PokemonShape(TableBase
):
622 __tablename__
= 'pokemon_shapes'
623 id = Column(Integer
, primary_key
=True, nullable
=False)
624 name
= Column(Unicode(24), nullable
=False)
625 awesome_name
= Column(Unicode(16), nullable
=False)
627 class PokemonStat(TableBase
):
628 __tablename__
= 'pokemon_stats'
629 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
630 stat_id
= Column(Integer
, ForeignKey('stats.id'), primary_key
=True, nullable
=False, autoincrement
=False)
631 base_stat
= Column(Integer
, nullable
=False)
632 effort
= Column(Integer
, nullable
=False)
634 class PokemonType(TableBase
):
635 __tablename__
= 'pokemon_types'
636 pokemon_id
= Column(Integer
, ForeignKey('pokemon.id'), primary_key
=True, nullable
=False, autoincrement
=False)
637 type_id
= Column(Integer
, ForeignKey('types.id'), nullable
=False)
638 slot
= Column(Integer
, primary_key
=True, nullable
=False, autoincrement
=False)
640 class Region(TableBase
):
641 """Major areas of the world: Kanto, Johto, etc."""
642 __tablename__
= 'regions'
643 id = Column(Integer
, primary_key
=True, nullable
=False)
644 name
= Column(Unicode(16), nullable
=False)
646 class Stat(TableBase
):
647 __tablename__
= 'stats'
648 id = Column(Integer
, primary_key
=True, nullable
=False)
649 damage_class_id
= Column(Integer
, ForeignKey('move_damage_classes.id'), nullable
=True)
650 name
= Column(Unicode(16), nullable
=False)
652 class SuperContestCombo(TableBase
):
653 __tablename__
= 'super_contest_combos'
654 first_move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
655 second_move_id
= Column(Integer
, ForeignKey('moves.id'), primary_key
=True, nullable
=False, autoincrement
=False)
657 class SuperContestEffect(TableBase
):
658 __tablename__
= 'super_contest_effects'
659 id = Column(Integer
, primary_key
=True, nullable
=False)
660 appeal
= Column(SmallInteger
, nullable
=False)
661 flavor_text
= Column(Unicode(64), nullable
=False)
663 class TypeEfficacy(TableBase
):
664 __tablename__
= 'type_efficacy'
665 damage_type_id
= Column(Integer
, ForeignKey('types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
666 target_type_id
= Column(Integer
, ForeignKey('types.id'), primary_key
=True, nullable
=False, autoincrement
=False)
667 damage_factor
= Column(Integer
, nullable
=False)
669 class Type(TableBase
):
670 __tablename__
= 'types'
671 __singlename__
= 'type'
672 id = Column(Integer
, primary_key
=True, nullable
=False)
673 name
= Column(Unicode(8), nullable
=False)
674 abbreviation
= Column(Unicode(3), nullable
=False)
675 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
676 damage_class_id
= Column(Integer
, ForeignKey('move_damage_classes.id'), nullable
=False) ## ??? is none; everything else is physical or special
678 class VersionGroup(TableBase
):
679 __tablename__
= 'version_groups'
680 id = Column(Integer
, primary_key
=True, nullable
=False)
681 generation_id
= Column(Integer
, ForeignKey('generations.id'), nullable
=False)
683 class VersionGroupRegion(TableBase
):
684 __tablename__
= 'version_group_regions'
685 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), primary_key
=True, nullable
=False)
686 region_id
= Column(Integer
, ForeignKey('regions.id'), primary_key
=True, nullable
=False)
688 class Version(TableBase
):
689 __tablename__
= 'versions'
690 id = Column(Integer
, primary_key
=True, nullable
=False)
691 version_group_id
= Column(Integer
, ForeignKey('version_groups.id'), nullable
=False)
692 name
= Column(Unicode(32), nullable
=False)
695 ### Relations down here, to avoid ordering problems
696 Ability
.flavor_text
= relation(AbilityFlavorText
, order_by
=AbilityFlavorText
.version_group_id
, backref
='ability')
697 Ability
.foreign_names
= relation(AbilityName
, backref
='ability')
698 Ability
.generation
= relation(Generation
, backref
='abilities')
700 AbilityFlavorText
.version_group
= relation(VersionGroup
)
702 AbilityName
.language
= relation(Language
)
704 Berry
.berry_firmness
= relation(BerryFirmness
, backref
='berries')
705 Berry
.firmness
= association_proxy('berry_firmness', 'name')
706 Berry
.flavors
= relation(BerryFlavor
, order_by
=BerryFlavor
.contest_type_id
, backref
='berry')
707 Berry
.natural_gift_type
= relation(Type
)
709 BerryFlavor
.contest_type
= relation(ContestType
)
711 ContestCombo
.first
= relation(Move
, primaryjoin
=ContestCombo
.first_move_id
==Move
.id,
712 backref
='contest_combo_first')
713 ContestCombo
.second
= relation(Move
, primaryjoin
=ContestCombo
.second_move_id
==Move
.id,
714 backref
='contest_combo_second')
716 Encounter
.location_area
= relation(LocationArea
, backref
='encounters')
717 Encounter
.pokemon
= relation(Pokemon
, backref
='encounters')
718 Encounter
.version
= relation(Version
, backref
='encounters')
719 Encounter
.slot
= relation(EncounterSlot
, backref
='encounters')
721 EncounterConditionValue
.condition
= relation(EncounterCondition
, backref
='values')
723 Encounter
.condition_value_map
= relation(EncounterConditionValueMap
, backref
='encounter')
724 Encounter
.condition_values
= association_proxy('condition_value_map', 'condition_value')
725 EncounterConditionValueMap
.condition_value
= relation(EncounterConditionValue
,
726 backref
='encounter_map')
728 EncounterSlot
.terrain
= relation(EncounterTerrain
, backref
='slots')
730 EncounterSlot
.condition_map
= relation(EncounterSlotCondition
, backref
='slot')
731 EncounterSlot
.conditions
= association_proxy('condition_map', 'condition')
732 EncounterSlotCondition
.condition
= relation(EncounterCondition
,
735 EvolutionChain
.growth_rate
= relation(GrowthRate
, backref
='evolution_chains')
737 Experience
.growth_rate
= relation(GrowthRate
, backref
='experience_table')
739 Generation
.canonical_pokedex
= relation(Pokedex
, backref
='canonical_for_generation')
740 Generation
.versions
= relation(Version
, secondary
=VersionGroup
.__table__
)
741 Generation
.main_region
= relation(Region
)
743 GrowthRate
.max_experience_obj
= relation(Experience
, primaryjoin
=and_(Experience
.growth_rate_id
== GrowthRate
.id, Experience
.level
== 100), uselist
=False)
744 GrowthRate
.max_experience
= association_proxy('max_experience_obj', 'experience')
746 Item
.berry
= relation(Berry
, uselist
=False, backref
='item')
747 Item
.flags
= relation(ItemFlag
, secondary
=ItemFlagMap
.__table__
)
748 Item
.flavor_text
= relation(ItemFlavorText
, order_by
=ItemFlavorText
.version_group_id
.asc(), backref
='item')
749 Item
.fling_effect
= relation(ItemFlingEffect
, backref
='items')
750 Item
.machines
= relation(Machine
, order_by
=Machine
.version_group_id
.asc())
751 Item
.category
= relation(ItemCategory
)
752 Item
.pocket
= association_proxy('category', 'pocket')
754 ItemCategory
.items
= relation(Item
, order_by
=Item
.name
)
755 ItemCategory
.pocket
= relation(ItemPocket
)
757 ItemFlavorText
.version_group
= relation(VersionGroup
)
759 ItemPocket
.categories
= relation(ItemCategory
, order_by
=ItemCategory
.name
)
761 Location
.region
= relation(Region
, backref
='locations')
763 LocationArea
.location
= relation(Location
, backref
='areas')
765 Machine
.item
= relation(Item
)
766 Machine
.version_group
= relation(VersionGroup
)
768 Move
.contest_effect
= relation(ContestEffect
, backref
='moves')
769 Move
.contest_combo_next
= association_proxy('contest_combo_first', 'second')
770 Move
.contest_combo_prev
= association_proxy('contest_combo_second', 'first')
771 Move
.contest_type
= relation(ContestType
, backref
='moves')
772 Move
.damage_class
= relation(MoveDamageClass
, backref
='moves')
773 Move
.flags
= association_proxy('move_flags', 'flag')
774 Move
.flavor_text
= relation(MoveFlavorText
, order_by
=MoveFlavorText
.version_group_id
, backref
='move')
775 Move
.foreign_names
= relation(MoveName
, backref
='move')
776 Move
.generation
= relation(Generation
, backref
='moves')
777 Move
.machines
= relation(Machine
, backref
='move')
778 Move
.move_effect
= relation(MoveEffect
, backref
='moves')
779 Move
.move_flags
= relation(MoveFlag
, backref
='move')
780 Move
.super_contest_effect
= relation(SuperContestEffect
, backref
='moves')
781 Move
.super_contest_combo_next
= association_proxy('super_contest_combo_first', 'second')
782 Move
.super_contest_combo_prev
= association_proxy('super_contest_combo_second', 'first')
783 Move
.target
= relation(MoveTarget
, backref
='moves')
784 Move
.type = relation(Type
, backref
='moves')
786 Move
.effect
= markdown
.MoveEffectProperty('effect')
787 Move
.priority
= association_proxy('move_effect', 'priority')
788 Move
.short_effect
= markdown
.MoveEffectProperty('short_effect')
790 MoveEffect
.category_map
= relation(MoveEffectCategoryMap
)
791 MoveEffect
.categories
= association_proxy('category_map', 'category')
792 MoveEffectCategoryMap
.category
= relation(MoveEffectCategory
)
794 MoveFlag
.flag
= relation(MoveFlagType
)
796 MoveFlavorText
.version_group
= relation(VersionGroup
)
798 MoveName
.language
= relation(Language
)
800 Nature
.foreign_names
= relation(NatureName
, backref
='nature')
801 Nature
.decreased_stat
= relation(Stat
, primaryjoin
=Nature
.decreased_stat_id
==Stat
.id,
802 backref
='decreasing_natures')
803 Nature
.increased_stat
= relation(Stat
, primaryjoin
=Nature
.increased_stat_id
==Stat
.id,
804 backref
='increasing_natures')
805 Nature
.hates_flavor
= relation(ContestType
, primaryjoin
=Nature
.hates_flavor_id
==ContestType
.id,
806 backref
='hating_natures')
807 Nature
.likes_flavor
= relation(ContestType
, primaryjoin
=Nature
.likes_flavor_id
==ContestType
.id,
808 backref
='liking_natures')
809 Nature
.battle_style_preferences
= relation(NatureBattleStylePreference
,
810 order_by
=NatureBattleStylePreference
.move_battle_style_id
,
812 Nature
.pokeathlon_effects
= relation(NaturePokeathlonStat
, order_by
=NaturePokeathlonStat
.pokeathlon_stat_id
)
814 NatureBattleStylePreference
.battle_style
= relation(MoveBattleStyle
, backref
='nature_preferences')
816 NatureName
.language
= relation(Language
)
818 NaturePokeathlonStat
.pokeathlon_stat
= relation(PokeathlonStat
, backref
='nature_effects')
820 Pokedex
.region
= relation(Region
, backref
='pokedexes')
821 Pokedex
.version_groups
= relation(VersionGroup
, secondary
=PokedexVersionGroup
.__table__
, backref
='pokedexes')
823 Pokemon
.abilities
= relation(Ability
, secondary
=PokemonAbility
.__table__
,
824 order_by
=PokemonAbility
.slot
,
826 Pokemon
.formes
= relation(Pokemon
, primaryjoin
=Pokemon
.id==Pokemon
.forme_base_pokemon_id
,
827 backref
=backref('forme_base_pokemon',
828 remote_side
=[Pokemon
.id]))
829 Pokemon
.pokemon_color
= relation(PokemonColor
, backref
='pokemon')
830 Pokemon
.color
= association_proxy('pokemon_color', 'name')
831 Pokemon
.dex_numbers
= relation(PokemonDexNumber
, order_by
=PokemonDexNumber
.pokedex_id
.asc(), backref
='pokemon')
832 Pokemon
.default_form_sprite
= relation(PokemonFormSprite
,
834 Pokemon
.id==PokemonFormSprite
.pokemon_id
,
835 PokemonFormSprite
.is_default
==True,
838 Pokemon
.egg_groups
= relation(EggGroup
, secondary
=PokemonEggGroup
.__table__
,
839 order_by
=PokemonEggGroup
.egg_group_id
,
841 Pokemon
.evolution_chain
= relation(EvolutionChain
, backref
='pokemon')
842 Pokemon
.child_pokemon
= relation(Pokemon
,
843 primaryjoin
=Pokemon
.id==PokemonEvolution
.from_pokemon_id
,
844 secondary
=PokemonEvolution
.__table__
,
845 secondaryjoin
=PokemonEvolution
.to_pokemon_id
==Pokemon
.id,
846 backref
=backref('parent_pokemon', uselist
=False),
848 Pokemon
.flavor_text
= relation(PokemonFlavorText
, order_by
=PokemonFlavorText
.version_id
.asc(), backref
='pokemon')
849 Pokemon
.foreign_names
= relation(PokemonName
, backref
='pokemon')
850 Pokemon
.pokemon_habitat
= relation(PokemonHabitat
, backref
='pokemon')
851 Pokemon
.habitat
= association_proxy('pokemon_habitat', 'name')
852 Pokemon
.items
= relation(PokemonItem
, backref
='pokemon')
853 Pokemon
.generation
= relation(Generation
, backref
='pokemon')
854 Pokemon
.shape
= relation(PokemonShape
, backref
='pokemon')
855 Pokemon
.stats
= relation(PokemonStat
, backref
='pokemon')
856 Pokemon
.types
= relation(Type
, secondary
=PokemonType
.__table__
, order_by
=PokemonType
.slot
.asc())
858 PokemonDexNumber
.pokedex
= relation(Pokedex
)
860 PokemonEvolution
.from_pokemon
= relation(Pokemon
,
861 primaryjoin
=PokemonEvolution
.from_pokemon_id
==Pokemon
.id,
862 backref
='child_evolutions',
864 PokemonEvolution
.to_pokemon
= relation(Pokemon
,
865 primaryjoin
=PokemonEvolution
.to_pokemon_id
==Pokemon
.id,
866 backref
=backref('parent_evolution', uselist
=False),
868 PokemonEvolution
.child_evolutions
= relation(PokemonEvolution
,
869 primaryjoin
=PokemonEvolution
.from_pokemon_id
==PokemonEvolution
.to_pokemon_id
,
870 foreign_keys
=[PokemonEvolution
.to_pokemon_id
],
871 backref
=backref('parent_evolution',
872 remote_side
=[PokemonEvolution
.from_pokemon_id
],
876 PokemonEvolution
.trigger
= relation(EvolutionTrigger
, backref
='evolutions')
877 PokemonEvolution
.trigger_item
= relation(Item
,
878 primaryjoin
=PokemonEvolution
.trigger_item_id
==Item
.id,
879 backref
='triggered_evolutions',
881 PokemonEvolution
.held_item
= relation(Item
,
882 primaryjoin
=PokemonEvolution
.held_item_id
==Item
.id,
883 backref
='required_for_evolutions',
885 PokemonEvolution
.location
= relation(Location
, backref
='triggered_evolutions')
886 PokemonEvolution
.known_move
= relation(Move
, backref
='triggered_evolutions')
887 PokemonEvolution
.party_pokemon
= relation(Pokemon
,
888 primaryjoin
=PokemonEvolution
.party_pokemon_id
==Pokemon
.id,
889 backref
='triggered_evolutions',
892 PokemonFlavorText
.version
= relation(Version
)
894 PokemonItem
.item
= relation(Item
, backref
='pokemon')
895 PokemonItem
.version
= relation(Version
)
897 PokemonFormGroup
.pokemon
= relation(Pokemon
, backref
=backref('form_group',
899 PokemonFormSprite
.pokemon
= relation(Pokemon
, backref
='form_sprites')
900 PokemonFormSprite
.introduced_in
= relation(VersionGroup
)
902 PokemonMove
.pokemon
= relation(Pokemon
, backref
='pokemon_moves')
903 PokemonMove
.version_group
= relation(VersionGroup
)
904 PokemonMove
.machine
= relation(Machine
, backref
='pokemon_moves',
905 primaryjoin
=and_(Machine
.version_group_id
==PokemonMove
.version_group_id
,
906 Machine
.move_id
==PokemonMove
.move_id
),
907 foreign_keys
=[Machine
.version_group_id
, Machine
.move_id
],
909 PokemonMove
.move
= relation(Move
, backref
='pokemon_moves')
910 PokemonMove
.method
= relation(PokemonMoveMethod
)
912 PokemonName
.language
= relation(Language
)
914 PokemonStat
.stat
= relation(Stat
)
916 # This is technically a has-many; Generation.main_region_id -> Region.id
917 Region
.generation
= relation(Generation
, uselist
=False)
918 Region
.version_group_regions
= relation(VersionGroupRegion
, backref
='region',
919 order_by
='VersionGroupRegion.version_group_id')
920 Region
.version_groups
= association_proxy('version_group_regions', 'version_group')
922 Stat
.damage_class
= relation(MoveDamageClass
, backref
='stats')
924 SuperContestCombo
.first
= relation(Move
, primaryjoin
=SuperContestCombo
.first_move_id
==Move
.id,
925 backref
='super_contest_combo_first')
926 SuperContestCombo
.second
= relation(Move
, primaryjoin
=SuperContestCombo
.second_move_id
==Move
.id,
927 backref
='super_contest_combo_second')
929 Type
.damage_efficacies
= relation(TypeEfficacy
,
931 ==TypeEfficacy
.damage_type_id
,
932 backref
='damage_type')
933 Type
.target_efficacies
= relation(TypeEfficacy
,
935 ==TypeEfficacy
.target_type_id
,
936 backref
='target_type')
938 Type
.generation
= relation(Generation
, backref
='types')
939 Type
.damage_class
= relation(MoveDamageClass
, backref
='types')
941 Version
.version_group
= relation(VersionGroup
, backref
='versions')
942 Version
.generation
= association_proxy('version_group', 'generation')
944 VersionGroup
.generation
= relation(Generation
, backref
='version_groups')
945 VersionGroup
.version_group_regions
= relation(VersionGroupRegion
, backref
='version_group')
946 VersionGroup
.regions
= association_proxy('version_group_regions', 'region')