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