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