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