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