9e0dc8853469fe58dd657b9e83d9859a2e0dea8f
[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 Generation(TableBase):
176 __tablename__ = 'generations'
177 id = Column(Integer, primary_key=True, nullable=False)
178 main_region_id = Column(Integer, ForeignKey('regions.id'))
179 canonical_pokedex_id = Column(Integer, ForeignKey('pokedexes.id'))
180 name = Column(Unicode(16), nullable=False)
181
182 class GrowthRate(TableBase):
183 """`formula` is written in LaTeX math notation."""
184 __tablename__ = 'growth_rates'
185 id = Column(Integer, primary_key=True, nullable=False)
186 name = Column(Unicode(20), nullable=False)
187 formula = Column(Unicode(500), nullable=False)
188
189 class Item(TableBase):
190 __tablename__ = 'items'
191 __singlename__ = 'item'
192 id = Column(Integer, primary_key=True, nullable=False)
193 name = Column(Unicode(16), nullable=False)
194 category_id = Column(Integer, ForeignKey('item_categories.id'), nullable=False)
195 cost = Column(Integer, nullable=False)
196 fling_power = Column(Integer, nullable=True)
197 fling_effect_id = Column(Integer, ForeignKey('item_fling_effects.id'), nullable=True)
198 flavor_text = Column(Unicode(255), nullable=False)
199 effect = Column(Unicode(5120), nullable=False)
200 is_underground = Column(Boolean, nullable=False)
201 can_hold = Column(Boolean, nullable=False)
202 is_battle_item = Column(Boolean, nullable=False)
203 can_use_automatically = Column(Boolean, nullable=False)
204 can_reuse = Column(Boolean, nullable=False)
205
206 class ItemCategory(TableBase):
207 __tablename__ = 'item_categories'
208 id = Column(Integer, primary_key=True, nullable=False)
209 pocket_id = Column(Integer, ForeignKey('item_pockets.id'), nullable=False)
210 name = Column(Unicode(16), nullable=False)
211
212 class ItemFlingEffect(TableBase):
213 __tablename__ = 'item_fling_effects'
214 id = Column(Integer, primary_key=True, nullable=False)
215 effect = Column(Unicode(255), nullable=False)
216
217 class ItemPocket(TableBase):
218 __tablename__ = 'item_pockets'
219 id = Column(Integer, primary_key=True, nullable=False)
220 identifier = Column(Unicode(16), nullable=False)
221 name = Column(Unicode(16), nullable=False)
222
223 class Language(TableBase):
224 __tablename__ = 'languages'
225 id = Column(Integer, primary_key=True, nullable=False)
226 iso639 = Column(Unicode(2), nullable=False)
227 iso3166 = Column(Unicode(2), nullable=False)
228 name = Column(Unicode(16), nullable=False)
229
230 class Location(TableBase):
231 __tablename__ = 'locations'
232 __singlename__ = 'location'
233 id = Column(Integer, primary_key=True, nullable=False)
234 region_id = Column(Integer, ForeignKey('regions.id'))
235 name = Column(Unicode(64), nullable=False)
236
237 class LocationArea(TableBase):
238 __tablename__ = 'location_areas'
239 id = Column(Integer, primary_key=True, nullable=False)
240 location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
241 internal_id = Column(Integer, nullable=False)
242 name = Column(Unicode(64), nullable=True)
243
244 class LocationAreaEncounterRate(TableBase):
245 __tablename__ = 'location_area_encounter_rates'
246 location_area_id = Column(Integer, ForeignKey('location_areas.id'), primary_key=True, nullable=False, autoincrement=False)
247 encounter_terrain_id = Column(Integer, ForeignKey('encounter_terrain.id'), primary_key=True, nullable=False, autoincrement=False)
248 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, autoincrement=False)
249 rate = Column(Integer, nullable=True)
250
251 class Machine(TableBase):
252 __tablename__ = 'machines'
253 machine_number = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
254 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
255 move_id = Column(Integer, ForeignKey('moves.id'), nullable=False)
256
257 class MoveBattleStyle(TableBase):
258 __tablename__ = 'move_battle_styles'
259 id = Column(Integer, primary_key=True, nullable=False)
260 name = Column(Unicode(8), nullable=False)
261
262 class MoveEffectCategory(TableBase):
263 __tablename__ = 'move_effect_categories'
264 id = Column(Integer, primary_key=True, nullable=False)
265 name = Column(Unicode(64), nullable=False)
266 can_affect_user = Column(Boolean, nullable=False)
267
268 class MoveEffectCategoryMap(TableBase):
269 __tablename__ = 'move_effect_category_map'
270 move_effect_id = Column(Integer, ForeignKey('move_effects.id'), primary_key=True, nullable=False)
271 move_effect_category_id = Column(Integer, ForeignKey('move_effect_categories.id'), primary_key=True, nullable=False)
272 affects_user = Column(Boolean, primary_key=True, nullable=False)
273
274 class MoveDamageClass(TableBase):
275 __tablename__ = 'move_damage_classes'
276 id = Column(Integer, primary_key=True, nullable=False)
277 name = Column(Unicode(8), nullable=False)
278 description = Column(Unicode(64), nullable=False)
279
280 class MoveEffect(TableBase):
281 __tablename__ = 'move_effects'
282 id = Column(Integer, primary_key=True, nullable=False)
283 priority = Column(SmallInteger, nullable=False)
284 short_effect = Column(Unicode(256), nullable=False)
285 effect = Column(Unicode(5120), nullable=False)
286
287 class MoveFlag(TableBase):
288 __tablename__ = 'move_flags'
289 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
290 move_flag_type_id = Column(Integer, ForeignKey('move_flag_types.id'), primary_key=True, nullable=False, autoincrement=False)
291
292 class MoveFlagType(TableBase):
293 __tablename__ = 'move_flag_types'
294 id = Column(Integer, primary_key=True, nullable=False)
295 name = Column(Unicode(32), nullable=False)
296 description = Column(rst.RstTextColumn(128), nullable=False)
297
298 class MoveFlavorText(TableBase):
299 __tablename__ = 'move_flavor_text'
300 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
301 generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, nullable=False, autoincrement=False)
302 flavor_text = Column(Unicode(255), nullable=False)
303
304 class MoveName(TableBase):
305 __tablename__ = 'move_names'
306 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
307 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
308 name = Column(Unicode(16), nullable=False)
309
310 class MoveTarget(TableBase):
311 __tablename__ = 'move_targets'
312 id = Column(Integer, primary_key=True, nullable=False)
313 name = Column(Unicode(32), nullable=False)
314 description = Column(Unicode(128), nullable=False)
315
316 class Move(TableBase):
317 __tablename__ = 'moves'
318 __singlename__ = 'move'
319 id = Column(Integer, primary_key=True, nullable=False)
320 name = Column(Unicode(12), nullable=False)
321 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
322 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
323 power = Column(SmallInteger)
324 pp = Column(SmallInteger, nullable=False)
325 accuracy = Column(SmallInteger)
326 target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False)
327 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False)
328 effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False)
329 effect_chance = Column(Integer)
330 contest_type_id = Column(Integer, ForeignKey('contest_types.id'), nullable=True)
331 contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=True)
332 super_contest_effect_id = Column(Integer, ForeignKey('super_contest_effects.id'), nullable=False)
333
334 class Nature(TableBase):
335 __tablename__ = 'natures'
336 __singlename__ = 'nature'
337 id = Column(Integer, primary_key=True, nullable=False)
338 name = Column(Unicode(8), nullable=False)
339 decreased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False)
340 increased_stat_id = Column(Integer, ForeignKey('stats.id'), nullable=False)
341 hates_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False)
342 likes_flavor_id = Column(Integer, ForeignKey('contest_types.id'), nullable=False)
343
344 class NatureBattleStylePreference(TableBase):
345 __tablename__ = 'nature_battle_style_preferences'
346 nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False)
347 move_battle_style_id = Column(Integer, ForeignKey('move_battle_styles.id'), primary_key=True, nullable=False)
348 low_hp_preference = Column(Integer, nullable=False)
349 high_hp_preference = Column(Integer, nullable=False)
350
351 class NaturePokeathlonStat(TableBase):
352 __tablename__ = 'nature_pokeathlon_stats'
353 nature_id = Column(Integer, ForeignKey('natures.id'), primary_key=True, nullable=False)
354 pokeathlon_stat_id = Column(Integer, ForeignKey('pokeathlon_stats.id'), primary_key=True, nullable=False)
355 max_change = Column(Integer, nullable=False)
356
357 class PokeathlonStat(TableBase):
358 __tablename__ = 'pokeathlon_stats'
359 id = Column(Integer, primary_key=True, nullable=False)
360 name = Column(Unicode(8), nullable=False)
361
362 class Pokedex(TableBase):
363 __tablename__ = 'pokedexes'
364 id = Column(Integer, primary_key=True, nullable=False)
365 region_id = Column(Integer, ForeignKey('regions.id'), nullable=True)
366 name = Column(Unicode(16), nullable=False)
367 description = Column(Unicode(512))
368
369 class PokedexVersionGroup(TableBase):
370 __tablename__ = 'pokedex_version_groups'
371 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
372 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
373
374 class Pokemon(TableBase):
375 """The core to this whole mess.
376
377 Note that I use both 'forme' and 'form' in both code and the database. I
378 only use 'forme' when specifically referring to Pokémon that have multiple
379 distinct species as forms—i.e., different stats or movesets. 'Form' is a
380 more general term referring to any variation within a species, including
381 purely cosmetic forms like Unown.
382 """
383 __tablename__ = 'pokemon'
384 __singlename__ = 'pokemon'
385 id = Column(Integer, primary_key=True, nullable=False)
386 name = Column(Unicode(20), nullable=False)
387 forme_name = Column(Unicode(16))
388 forme_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
389 generation_id = Column(Integer, ForeignKey('generations.id'))
390 evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'))
391 evolution_parent_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
392 evolution_method_id = Column(Integer, ForeignKey('evolution_methods.id'))
393 evolution_parameter = Column(Unicode(32))
394 height = Column(Integer, nullable=False)
395 weight = Column(Integer, nullable=False)
396 species = Column(Unicode(16), nullable=False)
397 color_id = Column(Integer, ForeignKey('pokemon_colors.id'), nullable=False)
398 pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=False)
399 habitat_id = Column(Integer, ForeignKey('pokemon_habitats.id'), nullable=True)
400 gender_rate = Column(Integer, nullable=False)
401 capture_rate = Column(Integer, nullable=False)
402 base_experience = Column(Integer, nullable=False)
403 base_happiness = Column(Integer, nullable=False)
404 is_baby = Column(Boolean, nullable=False)
405 has_gen4_fem_sprite = Column(Boolean, nullable=False)
406 has_gen4_fem_back_sprite = Column(Boolean, nullable=False)
407
408 ### Stuff to handle alternate Pokémon forms
409
410 @property
411 def national_id(self):
412 """Returns the National Pokédex number for this Pokémon. Use this
413 instead of the id directly; alternate formes may make the id incorrect.
414 """
415
416 if self.forme_base_pokemon_id:
417 return self.forme_base_pokemon_id
418 return self.id
419
420 @property
421 def full_name(self):
422 """Returns the name of this Pokémon, including its Forme, if any."""
423
424 if self.forme_name:
425 return "%s %s" % (self.forme_name.title(), self.name)
426 return self.name
427
428 @property
429 def normal_form(self):
430 """Returns the normal form for this Pokémon; i.e., this will return
431 regular Deoxys when called on any Deoxys form.
432 """
433
434 if self.forme_base_pokemon:
435 return self.forme_base_pokemon
436
437 return self
438
439 ### Not forms!
440
441 def stat(self, stat_name):
442 """Returns a PokemonStat record for the given stat name (or Stat row
443 object). Uses the normal has-many machinery, so all the stats are
444 effectively cached.
445 """
446 if isinstance(stat_name, Stat):
447 stat_name = stat_name.name
448
449 for pokemon_stat in self.stats:
450 if pokemon_stat.stat.name == stat_name:
451 return pokemon_stat
452
453 return None
454
455 class PokemonAbility(TableBase):
456 __tablename__ = 'pokemon_abilities'
457 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
458 ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False)
459 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
460
461 class PokemonColor(TableBase):
462 __tablename__ = 'pokemon_colors'
463 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
464 name = Column(Unicode(6), nullable=False)
465
466 class PokemonDexNumber(TableBase):
467 __tablename__ = 'pokemon_dex_numbers'
468 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
469 pokedex_id = Column(Integer, ForeignKey('pokedexes.id'), primary_key=True, nullable=False, autoincrement=False)
470 pokedex_number = Column(Integer, nullable=False)
471
472 class PokemonEggGroup(TableBase):
473 __tablename__ = 'pokemon_egg_groups'
474 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
475 egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False)
476
477 class PokemonFlavorText(TableBase):
478 __tablename__ = 'pokemon_flavor_text'
479 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
480 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
481 flavor_text = Column(Unicode(255), nullable=False)
482
483 class PokemonFormGroup(TableBase):
484 __tablename__ = 'pokemon_form_groups'
485 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
486 is_battle_only = Column(Boolean, nullable=False)
487 description = Column(Unicode(512), nullable=False)
488
489 class PokemonFormSprite(TableBase):
490 __tablename__ = 'pokemon_form_sprites'
491 id = Column(Integer, primary_key=True, nullable=False)
492 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
493 introduced_in_version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
494 name = Column(Unicode(16), nullable=True)
495 is_default = Column(Boolean, nullable=True)
496
497 class PokemonHabitat(TableBase):
498 __tablename__ = 'pokemon_habitats'
499 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
500 name = Column(Unicode(16), nullable=False)
501
502 class PokemonItem(TableBase):
503 __tablename__ = 'pokemon_items'
504 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
505 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
506 item_id = Column(Integer, ForeignKey('items.id'), primary_key=True, nullable=False, autoincrement=False)
507 rarity = Column(Integer, nullable=False)
508
509 class PokemonMove(TableBase):
510 __tablename__ = 'pokemon_moves'
511 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
512 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False, autoincrement=False)
513 move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False, index=True)
514 pokemon_move_method_id = Column(Integer, ForeignKey('pokemon_move_methods.id'), primary_key=True, nullable=False, autoincrement=False)
515 level = Column(Integer, primary_key=True, nullable=True, autoincrement=False)
516 order = Column(Integer, nullable=True)
517
518 class PokemonMoveMethod(TableBase):
519 __tablename__ = 'pokemon_move_methods'
520 id = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
521 name = Column(Unicode(64), nullable=False)
522 description = Column(Unicode(255), nullable=False)
523
524 class PokemonName(TableBase):
525 __tablename__ = 'pokemon_names'
526 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
527 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
528 name = Column(Unicode(16), nullable=False)
529
530 class PokemonShape(TableBase):
531 __tablename__ = 'pokemon_shapes'
532 id = Column(Integer, primary_key=True, nullable=False)
533 name = Column(Unicode(24), nullable=False)
534 awesome_name = Column(Unicode(16), nullable=False)
535
536 class PokemonStat(TableBase):
537 __tablename__ = 'pokemon_stats'
538 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
539 stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False)
540 base_stat = Column(Integer, nullable=False)
541 effort = Column(Integer, nullable=False)
542
543 class PokemonType(TableBase):
544 __tablename__ = 'pokemon_types'
545 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
546 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
547 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
548
549 class Region(TableBase):
550 """Major areas of the world: Kanto, Johto, etc."""
551 __tablename__ = 'regions'
552 id = Column(Integer, primary_key=True, nullable=False)
553 name = Column(Unicode(16), nullable=False)
554
555 class Stat(TableBase):
556 __tablename__ = 'stats'
557 id = Column(Integer, primary_key=True, nullable=False)
558 name = Column(Unicode(16), nullable=False)
559
560 class SuperContestCombo(TableBase):
561 __tablename__ = 'super_contest_combos'
562 first_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
563 second_move_id = Column(Integer, ForeignKey('moves.id'), primary_key=True, nullable=False, autoincrement=False)
564
565 class SuperContestEffect(TableBase):
566 __tablename__ = 'super_contest_effects'
567 id = Column(Integer, primary_key=True, nullable=False)
568 appeal = Column(SmallInteger, nullable=False)
569 flavor_text = Column(Unicode(64), nullable=False)
570
571 class TypeEfficacy(TableBase):
572 __tablename__ = 'type_efficacy'
573 damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
574 target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
575 damage_factor = Column(Integer, nullable=False)
576
577 class Type(TableBase):
578 __tablename__ = 'types'
579 __singlename__ = 'type'
580 id = Column(Integer, primary_key=True, nullable=False)
581 name = Column(Unicode(8), nullable=False)
582 abbreviation = Column(Unicode(3), nullable=False)
583 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
584 damage_class_id = Column(Integer, ForeignKey('move_damage_classes.id'), nullable=False) ## ??? is none; everything else is physical or special
585
586 class VersionGroup(TableBase):
587 __tablename__ = 'version_groups'
588 id = Column(Integer, primary_key=True, nullable=False)
589 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
590
591 class VersionGroupRegion(TableBase):
592 __tablename__ = 'version_group_regions'
593 version_group_id = Column(Integer, ForeignKey('version_groups.id'), primary_key=True, nullable=False)
594 region_id = Column(Integer, ForeignKey('regions.id'), primary_key=True, nullable=False)
595
596 class Version(TableBase):
597 __tablename__ = 'versions'
598 id = Column(Integer, primary_key=True, nullable=False)
599 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False)
600 name = Column(Unicode(32), nullable=False)
601
602
603 ### Relations down here, to avoid ordering problems
604 Berry.berry_firmness = relation(BerryFirmness, backref='berries')
605 Berry.firmness = association_proxy('berry_firmness', 'name')
606 Berry.flavors = relation(BerryFlavor, order_by=BerryFlavor.contest_type_id, backref='berry')
607 Berry.natural_gift_type = relation(Type)
608
609 BerryFlavor.contest_type = relation(ContestType)
610
611 ContestCombo.first = relation(Move, primaryjoin=ContestCombo.first_move_id==Move.id,
612 backref='contest_combo_first')
613 ContestCombo.second = relation(Move, primaryjoin=ContestCombo.second_move_id==Move.id,
614 backref='contest_combo_second')
615
616 Encounter.location_area = relation(LocationArea, backref='encounters')
617 Encounter.pokemon = relation(Pokemon, backref='encounters')
618 Encounter.version = relation(Version, backref='encounters')
619 Encounter.slot = relation(EncounterSlot, backref='encounters')
620
621 EncounterConditionValue.condition = relation(EncounterCondition, backref='values')
622
623 Encounter.condition_value_map = relation(EncounterConditionValueMap, backref='encounter')
624 Encounter.condition_values = association_proxy('condition_value_map', 'condition_value')
625 EncounterConditionValueMap.condition_value = relation(EncounterConditionValue,
626 backref='encounter_map')
627
628 EncounterSlot.terrain = relation(EncounterTerrain, backref='slots')
629
630 EncounterSlot.condition_map = relation(EncounterSlotCondition, backref='slot')
631 EncounterSlot.conditions = association_proxy('condition_map', 'condition')
632 EncounterSlotCondition.condition = relation(EncounterCondition,
633 backref='slot_map')
634
635 EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')
636
637 Generation.canonical_pokedex = relation(Pokedex, backref='canonical_for_generation')
638 Generation.versions = relation(Version, secondary=VersionGroup.__table__)
639 Generation.main_region = relation(Region)
640
641 Item.berry = relation(Berry, uselist=False, backref='item')
642 Item.fling_effect = relation(ItemFlingEffect, backref='items')
643 Item.category = relation(ItemCategory)
644 Item.pocket = association_proxy('category', 'pocket')
645
646 ItemCategory.items = relation(Item, order_by=Item.name)
647 ItemCategory.pocket = relation(ItemPocket)
648
649 ItemPocket.categories = relation(ItemCategory, order_by=ItemCategory.name)
650
651 Location.region = relation(Region, backref='locations')
652
653 LocationArea.location = relation(Location, backref='areas')
654
655 Machine.version_group = relation(VersionGroup)
656
657 Move.contest_effect = relation(ContestEffect, backref='moves')
658 Move.contest_combo_next = association_proxy('contest_combo_first', 'second')
659 Move.contest_combo_prev = association_proxy('contest_combo_second', 'first')
660 Move.contest_type = relation(ContestType, backref='moves')
661 Move.damage_class = relation(MoveDamageClass, backref='moves')
662 Move.flags = association_proxy('move_flags', 'flag')
663 Move.flavor_text = relation(MoveFlavorText, order_by=MoveFlavorText.generation_id, backref='move')
664 Move.foreign_names = relation(MoveName, backref='pokemon')
665 Move.generation = relation(Generation, backref='moves')
666 Move.machines = relation(Machine, backref='move')
667 Move.move_effect = relation(MoveEffect, backref='moves')
668 Move.move_flags = relation(MoveFlag, backref='move')
669 Move.super_contest_effect = relation(SuperContestEffect, backref='moves')
670 Move.super_contest_combo_next = association_proxy('super_contest_combo_first', 'second')
671 Move.super_contest_combo_prev = association_proxy('super_contest_combo_second', 'first')
672 Move.target = relation(MoveTarget, backref='moves')
673 Move.type = relation(Type, backref='moves')
674
675 Move.effect = rst.MoveEffectProperty('effect')
676 Move.priority = association_proxy('move_effect', 'priority')
677 Move.short_effect = rst.MoveEffectProperty('short_effect')
678
679 MoveEffect.category_map = relation(MoveEffectCategoryMap)
680 MoveEffect.categories = association_proxy('category_map', 'category')
681 MoveEffectCategoryMap.category = relation(MoveEffectCategory)
682
683 MoveFlag.flag = relation(MoveFlagType)
684
685 MoveFlavorText.generation = relation(Generation)
686
687 MoveName.language = relation(Language)
688
689 Nature.decreased_stat = relation(Stat, primaryjoin=Nature.decreased_stat_id==Stat.id,
690 backref='decreasing_natures')
691 Nature.increased_stat = relation(Stat, primaryjoin=Nature.increased_stat_id==Stat.id,
692 backref='increasing_natures')
693 Nature.hates_flavor = relation(ContestType, primaryjoin=Nature.hates_flavor_id==ContestType.id,
694 backref='hating_natures')
695 Nature.likes_flavor = relation(ContestType, primaryjoin=Nature.likes_flavor_id==ContestType.id,
696 backref='liking_natures')
697 Nature.battle_style_preferences = relation(NatureBattleStylePreference,
698 order_by=NatureBattleStylePreference.move_battle_style_id,
699 backref='nature')
700 Nature.pokeathlon_effects = relation(NaturePokeathlonStat, order_by=NaturePokeathlonStat.pokeathlon_stat_id)
701
702 NatureBattleStylePreference.battle_style = relation(MoveBattleStyle, backref='nature_preferences')
703
704 NaturePokeathlonStat.pokeathlon_stat = relation(PokeathlonStat, backref='nature_effects')
705
706 Pokedex.region = relation(Region, backref='pokedexes')
707 Pokedex.version_groups = relation(VersionGroup, secondary=PokedexVersionGroup.__table__, backref='pokedexes')
708
709 Pokemon.abilities = relation(Ability, secondary=PokemonAbility.__table__,
710 order_by=PokemonAbility.slot,
711 backref='pokemon')
712 Pokemon.formes = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.forme_base_pokemon_id,
713 backref=backref('forme_base_pokemon',
714 remote_side=[Pokemon.id]))
715 Pokemon.pokemon_color = relation(PokemonColor, backref='pokemon')
716 Pokemon.color = association_proxy('pokemon_color', 'name')
717 Pokemon.dex_numbers = relation(PokemonDexNumber, backref='pokemon')
718 Pokemon.default_form_sprite = relation(PokemonFormSprite,
719 primaryjoin=and_(
720 Pokemon.id==PokemonFormSprite.pokemon_id,
721 PokemonFormSprite.is_default==True,
722 ),
723 uselist=False)
724 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
725 order_by=PokemonEggGroup.egg_group_id,
726 backref='pokemon')
727 Pokemon.evolution_chain = relation(EvolutionChain, backref='pokemon')
728 Pokemon.evolution_method = relation(EvolutionMethod)
729 Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
730 backref=backref('evolution_parent',
731 remote_side=[Pokemon.id]))
732 Pokemon.flavor_text = relation(PokemonFlavorText, order_by=PokemonFlavorText.pokemon_id, backref='pokemon')
733 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
734 Pokemon.pokemon_habitat = relation(PokemonHabitat, backref='pokemon')
735 Pokemon.habitat = association_proxy('pokemon_habitat', 'name')
736 Pokemon.items = relation(PokemonItem, backref='pokemon')
737 Pokemon.generation = relation(Generation, backref='pokemon')
738 Pokemon.shape = relation(PokemonShape, backref='pokemon')
739 Pokemon.stats = relation(PokemonStat, backref='pokemon')
740 Pokemon.types = relation(Type, secondary=PokemonType.__table__)
741
742 PokemonDexNumber.pokedex = relation(Pokedex)
743
744 PokemonFlavorText.version = relation(Version)
745
746 PokemonItem.item = relation(Item, backref='pokemon')
747 PokemonItem.version = relation(Version)
748
749 PokemonFormGroup.pokemon = relation(Pokemon, backref=backref('form_group',
750 uselist=False))
751 PokemonFormSprite.pokemon = relation(Pokemon, backref='form_sprites')
752 PokemonFormSprite.introduced_in = relation(VersionGroup)
753
754 PokemonMove.pokemon = relation(Pokemon, backref='pokemon_moves')
755 PokemonMove.version_group = relation(VersionGroup)
756 PokemonMove.machine = relation(Machine, backref='pokemon_moves',
757 primaryjoin=and_(Machine.version_group_id==PokemonMove.version_group_id,
758 Machine.move_id==PokemonMove.move_id),
759 foreign_keys=[Machine.version_group_id, Machine.move_id],
760 uselist=False)
761 PokemonMove.move = relation(Move, backref='pokemon_moves')
762 PokemonMove.method = relation(PokemonMoveMethod)
763
764 PokemonName.language = relation(Language)
765
766 PokemonStat.stat = relation(Stat)
767
768 # This is technically a has-many; Generation.main_region_id -> Region.id
769 Region.generation = relation(Generation, uselist=False)
770 Region.version_group_regions = relation(VersionGroupRegion, backref='region',
771 order_by='VersionGroupRegion.version_group_id')
772 Region.version_groups = association_proxy('version_group_regions', 'version_group')
773
774 SuperContestCombo.first = relation(Move, primaryjoin=SuperContestCombo.first_move_id==Move.id,
775 backref='super_contest_combo_first')
776 SuperContestCombo.second = relation(Move, primaryjoin=SuperContestCombo.second_move_id==Move.id,
777 backref='super_contest_combo_second')
778
779 Type.damage_efficacies = relation(TypeEfficacy,
780 primaryjoin=Type.id
781 ==TypeEfficacy.damage_type_id,
782 backref='damage_type')
783 Type.target_efficacies = relation(TypeEfficacy,
784 primaryjoin=Type.id
785 ==TypeEfficacy.target_type_id,
786 backref='target_type')
787
788 Type.generation = relation(Generation, backref='types')
789 Type.damage_class = relation(MoveDamageClass, backref='types')
790
791 Version.version_group = relation(VersionGroup, backref='versions')
792 Version.generation = association_proxy('version_group', 'generation')
793
794 VersionGroup.generation = relation(Generation, backref='version_groups')
795 VersionGroup.version_group_regions = relation(VersionGroupRegion, backref='version_group')
796 VersionGroup.regions = association_proxy('version_group_regions', 'region')