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