a123231cb921a5377bdcaf509b117eeaa4464f41
[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 iso639 = Column(Unicode(2), nullable=False)
167 iso3166 = Column(Unicode(2), nullable=False)
168 name = Column(Unicode(16), nullable=False)
169
170 class Location(TableBase):
171 __tablename__ = 'locations'
172 __singlename__ = 'location'
173 id = Column(Integer, primary_key=True, nullable=False)
174 region_id = Column(Integer, ForeignKey('regions.id'))
175 name = Column(Unicode(64), nullable=False)
176
177 class LocationArea(TableBase):
178 __tablename__ = 'location_areas'
179 id = Column(Integer, primary_key=True, nullable=False)
180 location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
181 internal_id = Column(Integer, nullable=False)
182 name = Column(Unicode(64), nullable=True)
183
184 class LocationAreaEncounterRate(TableBase):
185 __tablename__ = 'location_area_encounter_rates'
186 location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
187 encounter_type_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
188 rate = Column(Integer, nullable=True)
189
190 class Machine(TableBase):
191 __tablename__ = 'machines'
192 machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
193 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
194 move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
195
196 class MoveEffectCategory(TableBase):
197 __tablename__ = 'move_effect_categories'
198 id = Column(Integer, primary_key=True, nullable=False)
199 name = Column(Unicode(64), nullable=False)
200 can_affect_user = Column(Boolean, nullable=False)
201
202 class MoveEffectCategoryMap(TableBase):
203 __tablename__ = 'move_effect_category_map'
204 move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False)
205 move_effect_category_id = Column(Integer, ForeignKey('move_effect_categories.id'), primary_key=True, nullable=False)
206 affects_user = Column(Boolean, primary_key=True, nullable=False)
207
208 class MoveDamageClass(TableBase):
209 __tablename__ = 'move_damage_classes'
210 id = Column(Integer, primary_key=True, nullable=False)
211 name = Column(Unicode(8), nullable=False)
212 description = Column(Unicode(64), nullable=False)
213
214 class MoveEffect(TableBase):
215 __tablename__ = 'move_effects'
216 id = Column(Integer, primary_key=True, nullable=False)
217 priority = Column(SmallInteger, nullable=False)
218 short_effect = Column(Unicode(256), nullable=False)
219 effect = Column(Unicode(5120), nullable=False)
220
221 class MoveFlag(TableBase):
222 __tablename__ = 'move_flags'
223 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
224 move_flag_type_id = Column(Integer, ForeignKey('move_flag_types.id'), primary_key=True, nullable=False, autoincrement=False)
225
226 class MoveFlagType(TableBase):
227 __tablename__ = 'move_flag_types'
228 id = Column(Integer, primary_key=True, nullable=False)
229 name = Column(Unicode(32), nullable=False)
230 description = Column(rst.RstTextColumn(128), nullable=False)
231
232 class MoveFlavorText(TableBase):
233 __tablename__ = 'move_flavor_text'
234 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
235 generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, nullable=False, autoincrement=False)
236 flavor_text = Column(Unicode(255), nullable=False)
237
238 class MoveName(TableBase):
239 __tablename__ = 'move_names'
240 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
241 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
242 name = Column(Unicode(16), nullable=False)
243
244 class MoveTarget(TableBase):
245 __tablename__ = 'move_targets'
246 id = Column(Integer, primary_key=True, nullable=False)
247 name = Column(Unicode(32), nullable=False)
248 description = Column(Unicode(128), nullable=False)
249
250 class Move(TableBase):
251 __tablename__ = 'moves'
252 __singlename__ = 'move'
253 id = Column(Integer, primary_key=True, nullable=False)
254 name = Column(Unicode(12), nullable=False)
255 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
256 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
257 power = Column(SmallInteger)
258 pp = Column(SmallInteger, nullable=False)
259 accuracy = Column(SmallInteger)
260 target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False)
261 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False)
262 effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False)
263 effect_chance = Column(Integer)
264 contest_type = Column(Unicode(8), nullable=False)
265 contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True)
266 super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=False)
267
268 class Pokedex(TableBase):
269 __tablename__ = 'pokedexes'
270 id = Column(Integer, primary_key=True, nullable=False)
271 name = Column(Unicode(16), nullable=False)
272 description = Column(Unicode(512))
273
274 class PokedexVersionGroup(TableBase):
275 __tablename__ = 'pokedex_version_groups'
276 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
277 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
278
279 class Pokemon(TableBase):
280 """The core to this whole mess.
281
282 Note that I use both 'forme' and 'form' in both code and the database. I
283 only use 'forme' when specifically referring to Pokémon that have multiple
284 distinct species as forms—i.e., different stats or movesets. 'Form' is a
285 more general term referring to any variation within a species, including
286 purely cosmetic forms like Unown.
287 """
288 __tablename__ = 'pokemon'
289 __singlename__ = 'pokemon'
290 id = Column(Integer, primary_key=True, nullable=False)
291 name = Column(Unicode(20), nullable=False)
292 forme_name = Column(Unicode(16))
293 forme_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
294 generation_id = Column(Integer, ForeignKey('generations.id'))
295 evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'))
296 evolution_parent_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
297 evolution_method_id = Column(Integer, ForeignKey('evolution_methods.id'))
298 evolution_parameter = Column(Unicode(32))
299 height = Column(Integer, nullable=False)
300 weight = Column(Integer, nullable=False)
301 species = Column(Unicode(16), nullable=False)
302 color_id = Column(Integer, ForeignKey('pokemon_colors.id'), nullable=False)
303 pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=False)
304 habitat_id = Column(Integer, ForeignKey('pokemon_habitats.id'), nullable=True)
305 gender_rate = Column(Integer, nullable=False)
306 capture_rate = Column(Integer, nullable=False)
307 base_experience = Column(Integer, nullable=False)
308 base_happiness = Column(Integer, nullable=False)
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.title(), 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 PokemonColor(TableBase):
351 __tablename__ = 'pokemon_colors'
352 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
353 name = Column(Unicode(6), nullable=False)
354
355 class PokemonDexNumber(TableBase):
356 __tablename__ = 'pokemon_dex_numbers'
357 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
358 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
359 pokedex_number = Column(Integer, nullable=False)
360
361 class PokemonEggGroup(TableBase):
362 __tablename__ = 'pokemon_egg_groups'
363 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
364 egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False)
365
366 class PokemonFlavorText(TableBase):
367 __tablename__ = 'pokemon_flavor_text'
368 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
369 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
370 flavor_text = Column(Unicode(255), nullable=False)
371
372 class PokemonFormGroup(TableBase):
373 __tablename__ = 'pokemon_form_groups'
374 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
375 is_battle_only = Column(Boolean, nullable=False)
376 description = Column(Unicode(512), nullable=False)
377
378 class PokemonFormSprite(TableBase):
379 __tablename__ = 'pokemon_form_sprites'
380 id = Column(Integer, primary_key=True, nullable=False)
381 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
382 introduced_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
383 name = Column(Unicode(16), nullable=True)
384 is_default = Column(Boolean, nullable=True)
385
386 class PokemonHabitat(TableBase):
387 __tablename__ = 'pokemon_habitats'
388 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
389 name = Column(Unicode(16), nullable=False)
390
391 class PokemonItem(TableBase):
392 __tablename__ = 'pokemon_items'
393 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
394 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
395 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False)
396 rarity = Column(Integer, nullable=False)
397
398 class PokemonMove(TableBase):
399 __tablename__ = 'pokemon_moves'
400 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
401 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
402 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False, index=True)
403 pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), primary_key=True, nullable=False, autoincrement=False)
404 level = Column(Integer, primary_key=True, nullable=True, autoincrement=False)
405 order = Column(Integer, nullable=True)
406
407 class PokemonMoveMethod(TableBase):
408 __tablename__ = 'pokemon_move_methods'
409 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
410 name = Column(Unicode(64), nullable=False)
411 description = Column(Unicode(255), nullable=False)
412
413 class PokemonName(TableBase):
414 __tablename__ = 'pokemon_names'
415 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
416 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
417 name = Column(Unicode(16), nullable=False)
418
419 class PokemonShape(TableBase):
420 __tablename__ = 'pokemon_shapes'
421 id = Column(Integer, primary_key=True, nullable=False)
422 name = Column(Unicode(24), nullable=False)
423 awesome_name = Column(Unicode(16), nullable=False)
424
425 class PokemonStat(TableBase):
426 __tablename__ = 'pokemon_stats'
427 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
428 stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False)
429 base_stat = Column(Integer, nullable=False)
430 effort = Column(Integer, nullable=False)
431
432 class PokemonType(TableBase):
433 __tablename__ = 'pokemon_types'
434 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
435 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
436 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
437
438 class Region(TableBase):
439 """Major areas of the world: Kanto, Johto, etc."""
440 __tablename__ = 'regions'
441 id = Column(Integer, primary_key=True, nullable=False)
442 name = Column(Unicode(16), nullable=False)
443
444 class Stat(TableBase):
445 __tablename__ = 'stats'
446 id = Column(Integer, primary_key=True, nullable=False)
447 name = Column(Unicode(16), nullable=False)
448
449 class SuperContestCombo(TableBase):
450 __tablename__ = 'super_contest_combos'
451 first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
452 second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
453
454 class SuperContestEffect(TableBase):
455 __tablename__ = 'super_contest_effects'
456 id = Column(Integer, primary_key=True, nullable=False)
457 appeal = Column(SmallInteger, nullable=False)
458 flavor_text = Column(Unicode(64), nullable=False)
459
460 class TypeEfficacy(TableBase):
461 __tablename__ = 'type_efficacy'
462 damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
463 target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
464 damage_factor = Column(Integer, nullable=False)
465
466 class Type(TableBase):
467 __tablename__ = 'types'
468 __singlename__ = 'type'
469 id = Column(Integer, primary_key=True, nullable=False)
470 name = Column(Unicode(8), nullable=False)
471 abbreviation = Column(Unicode(3), nullable=False)
472 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
473 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False) ## ??? is none; everything else is physical or special
474
475 class VersionGroup(TableBase):
476 __tablename__ = 'version_groups'
477 id = Column(Integer, primary_key=True, nullable=False)
478 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
479
480 class VersionGroupRegion(TableBase):
481 __tablename__ = 'version_group_regions'
482 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False)
483 region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False)
484
485 class Version(TableBase):
486 __tablename__ = 'versions'
487 id = Column(Integer, primary_key=True, nullable=False)
488 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False)
489 name = Column(Unicode(32), nullable=False)
490
491
492 ### Relations down here, to avoid ordering problems
493 ContestCombo.first = relation(Move, primaryjoin=ContestCombo.first_move_id==Move.id,
494 backref='contest_combo_first')
495 ContestCombo.second = relation(Move, primaryjoin=ContestCombo.second_move_id==Move.id,
496 backref='contest_combo_second')
497
498 Encounter.location_area = relation(LocationArea, backref='encounters')
499 Encounter.pokemon = relation(Pokemon, backref='encounters')
500 Encounter.version = relation(Version, backref='encounters')
501 Encounter.slot = relation(EncounterSlot, backref='encounters')
502
503 EncounterConditionValue.condition = relation(EncounterCondition, backref='values')
504
505 Encounter.condition_value_map = relation(EncounterConditionValueMap, backref='encounter')
506 Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
507 EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
508 backref='encounter_map')
509
510 EncounterSlot.terrain = relation(EncounterTerrain, backref='slots')
511
512 EncounterSlot.condition_map = relation(EncounterSlotCondition, backref='slot')
513 EncounterSlot.conditions = association_proxy('condition_map', 'condition')
514 EncounterSlotCondition.condition = relation(EncounterCondition,
515 backref='slot_map')
516
517 EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')
518
519 Generation.versions = relation(Version, secondary=VersionGroup.__table__)
520 Generation.main_region = relation(Region)
521
522 Location.region = relation(Region, backref='locations')
523
524 LocationArea.location = relation(Location, backref='areas')
525
526 Machine.version_group = relation(VersionGroup)
527
528 Move.contest_effect = relation(ContestEffect, backref='moves')
529 Move.contest_combo_next = association_proxy('contest_combo_first', 'second')
530 Move.contest_combo_prev = association_proxy('contest_combo_second', 'first')
531 Move.damage_class = relation(MoveDamageClass, backref='moves')
532 Move.flags = association_proxy('move_flags', 'flag')
533 Move.flavor_text = relation(MoveFlavorText, order_by=MoveFlavorText.generation_id, backref='move')
534 Move.foreign_names = relation(MoveName, backref='pokemon')
535 Move.generation = relation(Generation, backref='moves')
536 Move.machines = relation(Machine, backref='move')
537 Move.move_effect = relation(MoveEffect, backref='moves')
538 Move.move_flags = relation(MoveFlag, backref='move')
539 Move.super_contest_effect = relation(SuperContestEffect, backref='moves')
540 Move.super_contest_combo_next = association_proxy('super_contest_combo_first', 'second')
541 Move.super_contest_combo_prev = association_proxy('super_contest_combo_second', 'first')
542 Move.target = relation(MoveTarget, backref='moves')
543 Move.type = relation(Type, backref='moves')
544
545 Move.effect = rst.MoveEffectProperty('effect')
546 Move.priority = association_proxy('move_effect', 'priority')
547 Move.short_effect = rst.MoveEffectProperty('short_effect')
548
549 MoveEffect.category_map = relation(MoveEffectCategoryMap)
550 MoveEffect.categories = association_proxy('category_map', 'category')
551 MoveEffectCategoryMap.category = relation(MoveEffectCategory)
552
553 MoveFlag.flag = relation(MoveFlagType)
554
555 MoveFlavorText.generation = relation(Generation)
556
557 MoveName.language = relation(Language)
558
559 Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__)
560
561 Pokemon.abilities = relation(Ability, secondary=PokemonAbility.__table__,
562 order_by=PokemonAbility.slot,
563 backref='pokemon')
564 Pokemon.formes = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.forme_base_pokemon_id,
565 backref=backref('forme_base_pokemon',
566 remote_side=[Pokemon.id]))
567 Pokemon.pokemon_color = relation(PokemonColor, backref='pokemon')
568 Pokemon.color = association_proxy('pokemon_color', 'name')
569 Pokemon.dex_numbers = relation(PokemonDexNumber, backref='pokemon')
570 Pokemon.default_form_sprite = relation(PokemonFormSprite,
571 primaryjoin=and_(
572 Pokemon.id==PokemonFormSprite.pokemon_id,
573 PokemonFormSprite.is_default==True,
574 ),
575 uselist=False)
576 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
577 order_by=PokemonEggGroup.egg_group_id,
578 backref='pokemon')
579 Pokemon.evolution_chain = relation(EvolutionChain, backref='pokemon')
580 Pokemon.evolution_method = relation(EvolutionMethod)
581 Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
582 backref=backref('evolution_parent',
583 remote_side=[Pokemon.id]))
584 Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.pokemon_id, backref='pokemon')
585 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
586 Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
587 Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
588 Pokemon.items = relation(PokemonItem)
589 Pokemon.generation = relation(Generation, backref='pokemon')
590 Pokemon.shape = relation(PokemonShape, backref='pokemon')
591 Pokemon.stats = relation(PokemonStat, backref='pokemon')
592 Pokemon.types = relation(Type, secondary=PokemonType.__table__)
593
594 PokemonDexNumber.pokedex = relation(Pokedex)
595
596 PokemonFlavorText.version = relation(Version)
597
598 PokemonItem.item = relation(Item, backref='pokemon')
599 PokemonItem.version = relation(Version)
600
601 PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
602 uselist=False))
603 PokemonFormSprite.pokemon = relation(Pokemon, backref='form_sprites')
604 PokemonFormSprite.introduced_in = relation(VersionGroup)
605
606 PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
607 PokemonMove.version_group = relation(VersionGroup)
608 PokemonMove.machine = relation(Machine, backref='pokemon_moves',
609 primaryjoin=and_(Machine.version_group_id==PokemonMove.version_group_id,
610 Machine.move_id==PokemonMove.move_id),
611 foreign_keys=[Machine.version_group_id, Machine.move_id],
612 uselist=False)
613 PokemonMove.move = relation(Move, backref='pokemon_moves')
614 PokemonMove.method = relation(PokemonMoveMethod)
615
616 PokemonName.language = relation(Language)
617
618 PokemonStat.stat = relation(Stat)
619
620 # This is technically a has-many; Generation.main_region_id -> Region.id
621 Region.generation = relation(Generation, uselist=False)
622 Region.version_group_regions = relation(VersionGroupRegion, backref='region',
623 order_by='VersionGroupRegion.version_group_id')
624 Region.version_groups = association_proxy('version_group_regions', 'version_group')
625
626 SuperContestCombo.first = relation(Move, primaryjoin=SuperContestCombo.first_move_id==Move.id,
627 backref='super_contest_combo_first')
628 SuperContestCombo.second = relation(Move, primaryjoin=SuperContestCombo.second_move_id==Move.id,
629 backref='super_contest_combo_second')
630
631 Type.damage_efficacies = relation(TypeEfficacy,
632 primaryjoin=Type.id
633 ==TypeEfficacy.damage_type_id,
634 backref='damage_type')
635 Type.target_efficacies = relation(TypeEfficacy,
636 primaryjoin=Type.id
637 ==TypeEfficacy.target_type_id,
638 backref='target_type')
639
640 Type.generation = relation(Generation, backref='types')
641 Type.damage_class = relation(MoveDamageClass, backref='types')
642
643 Version.version_group = relation(VersionGroup, backref='versions')
644 Version.generation = association_proxy('version_group', 'generation')
645
646 VersionGroup.generation = relation(Generation, backref='version_groups')
647 VersionGroup.version_group_regions = relation(VersionGroupRegion, backref='version_group')
648 VersionGroup.regions = association_proxy('version_group_regions', 'region')