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