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