71b0e5bb43a250cd49810033ce5dfa48c06b8dc1
[zzz-pokedex.git] / pokedex / db / tables.py
1 # encoding: utf8
2
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.sql import and_
8 from sqlalchemy.types import *
9 from sqlalchemy.databases.mysql import *
10
11 from pokedex.db import rst
12
13 metadata = MetaData()
14 TableBase = declarative_base(metadata=metadata)
15
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 flavor_text = Column(Unicode(64), nullable=False)
22 effect = Column(Unicode(255), nullable=False)
23
24 class ContestCombo(TableBase):
25 __tablename__ = 'contest_combos'
26 first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
27 second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
28
29 class ContestEffect(TableBase):
30 __tablename__ = 'contest_effects'
31 id = Column(Integer, primary_key=True, nullable=False)
32 appeal = Column(SmallInteger, nullable=False)
33 jam = Column(SmallInteger, nullable=False)
34 flavor_text = Column(Unicode(64), nullable=False)
35 effect = Column(Unicode(255), nullable=False)
36
37 class EggGroup(TableBase):
38 __tablename__ = 'egg_groups'
39 id = Column(Integer, primary_key=True, nullable=False)
40 name = Column(Unicode(16), nullable=False)
41
42 class Encounter(TableBase):
43 """Rows in this table represent encounters with wild Pokémon. Bear with
44 me, here.
45
46 Within a given area in a given game, encounters are differentiated by the
47 "slot" they are in and the state of the game world.
48
49 What the player is doing to get an encounter, such as surfing or walking
50 through tall grass, is called terrain. Each terrain has its own set of
51 encounter slots.
52
53 Within a terrain, slots are defined primarily by rarity. Each slot can
54 also be affected by world conditions; for example, the 20% slot for walking
55 in tall grass is affected by whether a swarm is in effect in that area.
56 "Is there a swarm?" is a condition; "there is a swarm" and "there is not a
57 swarm" are the possible values of this condition.
58
59 A slot (20% walking in grass) and any appropriate world conditions (no
60 swarm) are thus enough to define a specific encounter.
61
62 Well, okay, almost: each slot actually appears twice.
63 """
64
65 __tablename__ = 'encounters'
66 id = Column(Integer, primary_key=True, nullable=False)
67 version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False)
68 location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False)
69 encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), nullable=False, autoincrement=False)
70 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False)
71 min_level = Column(Integer, nullable=False, autoincrement=False)
72 max_level = Column(Integer, nullable=False, autoincrement=False)
73
74 class EncounterCondition(TableBase):
75 """Rows in this table represent varying conditions in the game world, such
76 as time of day.
77 """
78
79 __tablename__ = 'encounter_conditions'
80 id = Column(Integer, primary_key=True, nullable=False)
81 name = Column(Unicode(64), nullable=False)
82
83 class EncounterConditionValue(TableBase):
84 """Rows in this table represent possible states for a condition; for
85 example, the state of 'swarm' could be 'swarm' or 'no swarm'.
86 """
87
88 __tablename__ = 'encounter_condition_values'
89 id = Column(Integer, primary_key=True, nullable=False)
90 encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=False, nullable=False, autoincrement=False)
91 name = Column(Unicode(64), nullable=False)
92 is_default = Column(Boolean, nullable=False)
93
94 class EncounterConditionValueMap(TableBase):
95 """Maps encounters to the specific conditions under which they occur."""
96
97 __tablename__ = 'encounter_condition_value_map'
98 encounter_id = Column(Integer, ForeignKey('encounters.id'), primary_key=True, nullable=False, autoincrement=False)
99 encounter_condition_value_id = Column(Integer, ForeignKey('encounter_condition_values.id'), primary_key=True, nullable=False, autoincrement=False)
100
101 class EncounterTerrain(TableBase):
102 """Rows in this table represent ways the player can enter a wild encounter,
103 e.g., surfing, fishing, or walking through tall grass.
104 """
105
106 __tablename__ = 'encounter_terrain'
107 id = Column(Integer, primary_key=True, nullable=False)
108 name = Column(Unicode(64), nullable=False)
109
110 class EncounterSlot(TableBase):
111 """Rows in this table represent an abstract "slot" within a terrain,
112 associated with both some set of conditions and a rarity.
113
114 Note that there are two encounters per slot, so the rarities will only add
115 up to 50.
116 """
117
118 __tablename__ = 'encounter_slots'
119 id = Column(Integer, primary_key=True, nullable=False)
120 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False, autoincrement=False)
121 encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=False, nullable=False, autoincrement=False)
122 rarity = Column(Integer, nullable=False, autoincrement=False)
123
124 class EncounterSlotCondition(TableBase):
125 """Lists all conditions that affect each slot."""
126
127 __tablename__ = 'encounter_slot_conditions'
128 encounter_slot_id = Column(Integer, ForeignKey('encounter_slots.id'), primary_key=True, nullable=False, autoincrement=False)
129 encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), primary_key=True, nullable=False, autoincrement=False)
130
131 class EvolutionChain(TableBase):
132 __tablename__ = 'evolution_chains'
133 id = Column(Integer, primary_key=True, nullable=False)
134 growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), nullable=False)
135 steps_to_hatch = Column(Integer, nullable=False)
136 baby_trigger_item = Column(Unicode(12))
137
138 class EvolutionMethod(TableBase):
139 __tablename__ = 'evolution_methods'
140 id = Column(Integer, primary_key=True, nullable=False)
141 name = Column(Unicode(64), nullable=False)
142 description = Column(Unicode(255), nullable=False)
143
144 class Generation(TableBase):
145 __tablename__ = 'generations'
146 id = Column(Integer, primary_key=True, nullable=False)
147 main_region_id = Column(Integer, ForeignKey('regions.id'))
148 name = Column(Unicode(16), nullable=False)
149
150 class GrowthRate(TableBase):
151 """`formula` is written in LaTeX math notation."""
152 __tablename__ = 'growth_rates'
153 id = Column(Integer, primary_key=True, nullable=False)
154 name = Column(Unicode(20), nullable=False)
155 formula = Column(Unicode(500), nullable=False)
156
157 class Item(TableBase):
158 __tablename__ = 'items'
159 __singlename__ = 'item'
160 id = Column(Integer, primary_key=True, nullable=False)
161 name = Column(Unicode(16), nullable=False)
162
163 class Language(TableBase):
164 __tablename__ = 'languages'
165 id = Column(Integer, primary_key=True, nullable=False)
166 iso3166 = Column(Unicode(2), nullable=False)
167 name = Column(Unicode(16), nullable=False)
168
169 class Location(TableBase):
170 __tablename__ = 'locations'
171 __singlename__ = 'location'
172 id = Column(Integer, primary_key=True, nullable=False)
173 region_id = Column(Integer, ForeignKey('regions.id'))
174 name = Column(Unicode(64), nullable=False)
175
176 class LocationArea(TableBase):
177 __tablename__ = 'location_areas'
178 id = Column(Integer, primary_key=True, nullable=False)
179 location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
180 internal_id = Column(Integer, nullable=False)
181 name = Column(Unicode(64), nullable=True)
182
183 class LocationAreaEncounterRate(TableBase):
184 __tablename__ = 'location_area_encounter_rates'
185 location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
186 encounter_type_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
187 rate = Column(Integer, nullable=True)
188
189 class Machine(TableBase):
190 __tablename__ = 'machines'
191 machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
192 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
193 move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
194
195 class MoveEffectCategory(TableBase):
196 __tablename__ = 'move_effect_categories'
197 id = Column(Integer, primary_key=True, nullable=False)
198 name = Column(Unicode(64), nullable=False)
199 can_affect_user = Column(Boolean, nullable=False)
200
201 class MoveEffectCategoryMap(TableBase):
202 __tablename__ = 'move_effect_category_map'
203 move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False)
204 move_effect_category_id = Column(Integer, ForeignKey('move_effect_categories.id'), primary_key=True, nullable=False)
205 affects_user = Column(Boolean, primary_key=True, nullable=False)
206
207 class MoveDamageClass(TableBase):
208 __tablename__ = 'move_damage_classes'
209 id = Column(Integer, primary_key=True, nullable=False)
210 name = Column(Unicode(8), nullable=False)
211 description = Column(Unicode(64), nullable=False)
212
213 class MoveEffect(TableBase):
214 __tablename__ = 'move_effects'
215 id = Column(Integer, primary_key=True, nullable=False)
216 priority = Column(SmallInteger, nullable=False)
217 short_effect = Column(Unicode(256), nullable=False)
218 effect = Column(Unicode(5120), nullable=False)
219
220 class MoveFlag(TableBase):
221 __tablename__ = 'move_flags'
222 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
223 move_flag_type_id = Column(Integer, ForeignKey('move_flag_types.id'), primary_key=True, nullable=False, autoincrement=False)
224
225 class MoveFlagType(TableBase):
226 __tablename__ = 'move_flag_types'
227 id = Column(Integer, primary_key=True, nullable=False)
228 name = Column(Unicode(32), nullable=False)
229 description = Column(rst.RstTextColumn(128), nullable=False)
230
231 class MoveFlavorText(TableBase):
232 __tablename__ = 'move_flavor_text'
233 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
234 generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, nullable=False, autoincrement=False)
235 flavor_text = Column(Unicode(255), nullable=False)
236
237 class MoveName(TableBase):
238 __tablename__ = 'move_names'
239 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
240 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
241 name = Column(Unicode(16), nullable=False)
242
243 class MoveTarget(TableBase):
244 __tablename__ = 'move_targets'
245 id = Column(Integer, primary_key=True, nullable=False)
246 name = Column(Unicode(32), nullable=False)
247 description = Column(Unicode(128), nullable=False)
248
249 class Move(TableBase):
250 __tablename__ = 'moves'
251 __singlename__ = 'move'
252 id = Column(Integer, primary_key=True, nullable=False)
253 name = Column(Unicode(12), nullable=False)
254 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
255 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
256 power = Column(SmallInteger)
257 pp = Column(SmallInteger, nullable=False)
258 accuracy = Column(SmallInteger)
259 target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False)
260 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False)
261 effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False)
262 effect_chance = Column(Integer)
263 contest_type = Column(Unicode(8), nullable=False)
264 contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True)
265 super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=False)
266
267 class Pokedex(TableBase):
268 __tablename__ = 'pokedexes'
269 id = Column(Integer, primary_key=True, nullable=False)
270 name = Column(Unicode(16), nullable=False)
271 description = Column(Unicode(512))
272
273 class PokedexVersionGroup(TableBase):
274 __tablename__ = 'pokedex_version_groups'
275 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
276 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
277
278 class Pokemon(TableBase):
279 """The core to this whole mess.
280
281 Note that I use both 'forme' and 'form' in both code and the database. I
282 only use 'forme' when specifically referring to Pokémon that have multiple
283 distinct species as forms—i.e., different stats or movesets. 'Form' is a
284 more general term referring to any variation within a species, including
285 purely cosmetic forms like Unown.
286 """
287 __tablename__ = 'pokemon'
288 __singlename__ = 'pokemon'
289 id = Column(Integer, primary_key=True, nullable=False)
290 name = Column(Unicode(20), nullable=False)
291 forme_name = Column(Unicode(16))
292 forme_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
293 generation_id = Column(Integer, ForeignKey('generations.id'))
294 evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'))
295 evolution_parent_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
296 evolution_method_id = Column(Integer, ForeignKey('evolution_methods.id'))
297 evolution_parameter = Column(Unicode(32))
298 height = Column(Integer, nullable=False)
299 weight = Column(Integer, nullable=False)
300 species = Column(Unicode(16), nullable=False)
301 color = Column(Unicode(6), nullable=False)
302 pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=False)
303 habitat = Column(Unicode(16), nullable=False)
304 gender_rate = Column(Integer, nullable=False)
305 capture_rate = Column(Integer, nullable=False)
306 base_experience = Column(Integer, nullable=False)
307 base_happiness = Column(Integer, nullable=False)
308 gen1_internal_id = Column(Integer)
309 is_baby = Column(Boolean, nullable=False)
310 has_gen4_fem_sprite = Column(Boolean, nullable=False)
311 has_gen4_fem_back_sprite = Column(Boolean, nullable=False)
312
313 ### Stuff to handle alternate Pokémon forms
314
315 @property
316 def national_id(self):
317 """Returns the National Pokédex number for this Pokémon. Use this
318 instead of the id directly; alternate formes may make the id incorrect.
319 """
320
321 if self.forme_base_pokemon_id:
322 return self.forme_base_pokemon_id
323 return self.id
324
325 @property
326 def full_name(self):
327 """Returns the name of this Pokémon, including its Forme, if any."""
328
329 if self.forme_name:
330 return "%s %s" % (self.forme_name.capitalize(), self.name)
331 return self.name
332
333 @property
334 def normal_form(self):
335 """Returns the normal form for this Pokémon; i.e., this will return
336 regular Deoxys when called on any Deoxys form.
337 """
338
339 if self.forme_base_pokemon:
340 return self.forme_base_pokemon
341
342 return self
343
344 class PokemonAbility(TableBase):
345 __tablename__ = 'pokemon_abilities'
346 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
347 ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False)
348 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
349
350 class PokemonDexNumber(TableBase):
351 __tablename__ = 'pokemon_dex_numbers'
352 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
353 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
354 pokedex_number = Column(Integer, nullable=False)
355
356 class PokemonEggGroup(TableBase):
357 __tablename__ = 'pokemon_egg_groups'
358 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
359 egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False)
360
361 class PokemonFlavorText(TableBase):
362 __tablename__ = 'pokemon_flavor_text'
363 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
364 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
365 flavor_text = Column(Unicode(255), nullable=False)
366
367 class PokemonFormGroup(TableBase):
368 __tablename__ = 'pokemon_form_groups'
369 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
370 description = Column(Unicode(512), nullable=False)
371
372 class PokemonFormSprite(TableBase):
373 __tablename__ = 'pokemon_form_sprites'
374 id = Column(Integer, primary_key=True, nullable=False)
375 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
376 introduced_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
377 name = Column(Unicode(16), nullable=True)
378
379 class PokemonItem(TableBase):
380 __tablename__ = 'pokemon_items'
381 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
382 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
383 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False)
384 rarity = Column(Integer, nullable=False)
385
386 class PokemonMove(TableBase):
387 __tablename__ = 'pokemon_moves'
388 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
389 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
390 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False, index=True)
391 pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), primary_key=True, nullable=False, autoincrement=False)
392 level = Column(Integer, primary_key=True, nullable=True, autoincrement=False)
393 order = Column(Integer, nullable=True)
394
395 class PokemonMoveMethod(TableBase):
396 __tablename__ = 'pokemon_move_methods'
397 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
398 name = Column(Unicode(64), nullable=False)
399 description = Column(Unicode(255), nullable=False)
400
401 class PokemonName(TableBase):
402 __tablename__ = 'pokemon_names'
403 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
404 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
405 name = Column(Unicode(16), nullable=False)
406
407 class PokemonShape(TableBase):
408 __tablename__ = 'pokemon_shapes'
409 id = Column(Integer, primary_key=True, nullable=False)
410 name = Column(Unicode(24), nullable=False)
411 awesome_name = Column(Unicode(16), nullable=False)
412
413 class PokemonStat(TableBase):
414 __tablename__ = 'pokemon_stats'
415 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
416 stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False)
417 base_stat = Column(Integer, nullable=False)
418 effort = Column(Integer, nullable=False)
419
420 class PokemonType(TableBase):
421 __tablename__ = 'pokemon_types'
422 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
423 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
424 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
425
426 class Region(TableBase):
427 """Major areas of the world: Kanto, Johto, etc."""
428 __tablename__ = 'regions'
429 id = Column(Integer, primary_key=True, nullable=False)
430 name = Column(Unicode(16), nullable=False)
431
432 class Stat(TableBase):
433 __tablename__ = 'stats'
434 id = Column(Integer, primary_key=True, nullable=False)
435 name = Column(Unicode(16), nullable=False)
436
437 class SuperContestCombo(TableBase):
438 __tablename__ = 'super_contest_combos'
439 first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
440 second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
441
442 class SuperContestEffect(TableBase):
443 __tablename__ = 'super_contest_effects'
444 id = Column(Integer, primary_key=True, nullable=False)
445 appeal = Column(SmallInteger, nullable=False)
446 flavor_text = Column(Unicode(64), nullable=False)
447
448 class TypeEfficacy(TableBase):
449 __tablename__ = 'type_efficacy'
450 damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
451 target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
452 damage_factor = Column(Integer, nullable=False)
453
454 class Type(TableBase):
455 __tablename__ = 'types'
456 __singlename__ = 'type'
457 id = Column(Integer, primary_key=True, nullable=False)
458 name = Column(Unicode(8), nullable=False)
459 abbreviation = Column(Unicode(3), nullable=False)
460 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
461 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False) ## ??? is none; everything else is physical or special
462
463 class VersionGroup(TableBase):
464 __tablename__ = 'version_groups'
465 id = Column(Integer, primary_key=True, nullable=False)
466 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
467
468 class VersionGroupRegion(TableBase):
469 __tablename__ = 'version_group_regions'
470 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False)
471 region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False)
472
473 class Version(TableBase):
474 __tablename__ = 'versions'
475 id = Column(Integer, primary_key=True, nullable=False)
476 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False)
477 name = Column(Unicode(32), nullable=False)
478
479
480 ### Relations down here, to avoid ordering problems
481 ContestCombo.first = relation(Move, primaryjoin=ContestCombo.first_move_id==Move.id,
482 backref='contest_combo_first')
483 ContestCombo.second = relation(Move, primaryjoin=ContestCombo.second_move_id==Move.id,
484 backref='contest_combo_second')
485
486 Encounter.location_area = relation(LocationArea, backref='encounters')
487 Encounter.pokemon = relation(Pokemon, backref='encounters')
488 Encounter.version = relation(Version, backref='encounters')
489 Encounter.slot = relation(EncounterSlot, backref='encounters')
490
491 EncounterConditionValue.condition = relation(EncounterCondition, backref='values')
492
493 Encounter.condition_value_map = relation(EncounterConditionValueMap, backref='encounter')
494 Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
495 EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
496 backref='encounter_map')
497
498 EncounterSlot.terrain = relation(EncounterTerrain, backref='slots')
499
500 EncounterSlot.condition_map = relation(EncounterSlotCondition, backref='slot')
501 EncounterSlot.conditions = association_proxy('condition_map', 'condition')
502 EncounterSlotCondition.condition = relation(EncounterCondition,
503 backref='slot_map')
504
505 EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')
506
507 Generation.versions = relation(Version, secondary=VersionGroup.__table__)
508 Generation.main_region = relation(Region)
509
510 Location.region = relation(Region, backref='locations')
511
512 LocationArea.location = relation(Location, backref='areas')
513
514 Machine.version_group = relation(VersionGroup)
515
516 Move.contest_effect = relation(ContestEffect, backref='moves')
517 Move.contest_combo_next = association_proxy('contest_combo_first', 'second')
518 Move.contest_combo_prev = association_proxy('contest_combo_second', 'first')
519 Move.damage_class = relation(MoveDamageClass, backref='moves')
520 Move.flags = association_proxy('move_flags', 'flag')
521 Move.flavor_text = relation(MoveFlavorText, order_by=MoveFlavorText.generation_id, backref='move')
522 Move.foreign_names = relation(MoveName, backref='pokemon')
523 Move.generation = relation(Generation, backref='moves')
524 Move.machines = relation(Machine, backref='move')
525 Move.move_effect = relation(MoveEffect, backref='moves')
526 Move.move_flags = relation(MoveFlag, backref='move')
527 Move.super_contest_effect = relation(SuperContestEffect, backref='moves')
528 Move.super_contest_combo_next = association_proxy('super_contest_combo_first', 'second')
529 Move.super_contest_combo_prev = association_proxy('super_contest_combo_second', 'first')
530 Move.target = relation(MoveTarget, backref='moves')
531 Move.type = relation(Type, backref='moves')
532
533 Move.effect = rst.MoveEffectProperty('effect')
534 Move.priority = association_proxy('move_effect', 'priority')
535 Move.short_effect = rst.MoveEffectProperty('short_effect')
536
537 MoveEffect.category_map = relation(MoveEffectCategoryMap)
538 MoveEffect.categories = association_proxy('category_map', 'category')
539 MoveEffectCategoryMap.category = relation(MoveEffectCategory)
540
541 MoveFlag.flag = relation(MoveFlagType)
542
543 MoveFlavorText.generation = relation(Generation)
544
545 MoveName.language = relation(Language)
546
547 Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__)
548
549 Pokemon.abilities = relation(Ability, secondary=PokemonAbility.__table__,
550 order_by=PokemonAbility.slot,
551 backref='pokemon')
552 Pokemon.formes = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.forme_base_pokemon_id,
553 backref=backref('forme_base_pokemon',
554 remote_side=[Pokemon.id]))
555 Pokemon.dex_numbers = relation(PokemonDexNumber, backref='pokemon')
556 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
557 order_by=PokemonEggGroup.egg_group_id,
558 backref='pokemon')
559 Pokemon.evolution_chain = relation(EvolutionChain, backref='pokemon')
560 Pokemon.evolution_method = relation(EvolutionMethod)
561 Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
562 backref=backref('evolution_parent',
563 remote_side=[Pokemon.id]))
564 Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.pokemon_id, backref='pokemon')
565 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
566 Pokemon.items = relation(PokemonItem)
567 Pokemon.generation = relation(Generation, backref='pokemon')
568 Pokemon.shape = relation(PokemonShape, backref='pokemon')
569 Pokemon.stats = relation(PokemonStat, backref='pokemon')
570 Pokemon.types = relation(Type, secondary=PokemonType.__table__)
571
572 PokemonDexNumber.pokedex = relation(Pokedex)
573
574 PokemonFlavorText.version = relation(Version)
575
576 PokemonItem.item = relation(Item, backref='pokemon')
577 PokemonItem.version = relation(Version)
578
579 PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
580 uselist=False))
581 PokemonFormSprite.pokemon = relation(Pokemon, backref='form_sprites')
582 PokemonFormSprite.introduced_in = relation(VersionGroup)
583
584 PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
585 PokemonMove.version_group = relation(VersionGroup)
586 PokemonMove.machine = relation(Machine, backref='pokemon_moves',
587 primaryjoin=and_(Machine.version_group_id==PokemonMove.version_group_id,
588 Machine.move_id==PokemonMove.move_id),
589 foreign_keys=[Machine.version_group_id, Machine.move_id],
590 uselist=False)
591 PokemonMove.move = relation(Move, backref='pokemon_moves')
592 PokemonMove.method = relation(PokemonMoveMethod)
593
594 PokemonName.language = relation(Language)
595
596 PokemonStat.stat = relation(Stat)
597
598 # This is technically a has-many; Generation.main_region_id -> Region.id
599 Region.generation = relation(Generation, uselist=False)
600 Region.version_group_regions = relation(VersionGroupRegion, backref='region',
601 order_by='VersionGroupRegion.version_group_id')
602 Region.version_groups = association_proxy('version_group_regions', 'version_group')
603
604 SuperContestCombo.first = relation(Move, primaryjoin=SuperContestCombo.first_move_id==Move.id,
605 backref='super_contest_combo_first')
606 SuperContestCombo.second = relation(Move, primaryjoin=SuperContestCombo.second_move_id==Move.id,
607 backref='super_contest_combo_second')
608
609 Type.damage_efficacies = relation(TypeEfficacy,
610 primaryjoin=Type.id
611 ==TypeEfficacy.damage_type_id,
612 backref='damage_type')
613 Type.target_efficacies = relation(TypeEfficacy,
614 primaryjoin=Type.id
615 ==TypeEfficacy.target_type_id,
616 backref='target_type')
617
618 Type.generation = relation(Generation, backref='types')
619 Type.damage_class = relation(MoveDamageClass, backref='types')
620
621 Version.version_group = relation(VersionGroup, backref='versions')
622 Version.generation = association_proxy('version_group', 'generation')
623
624 VersionGroup.generation = relation(Generation, backref='version_groups')
625 VersionGroup.version_group_regions = relation(VersionGroupRegion, backref='version_group')
626 VersionGroup.regions = association_proxy('version_group_regions', 'region')