95961d39202ac0f1e9fa95c1ea7e987e974b073c
[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.orm import backref, relation
6 from sqlalchemy.types import *
7 from sqlalchemy.databases.mysql import *
8
9 metadata = MetaData()
10 TableBase = declarative_base(metadata=metadata)
11
12 class Ability(TableBase):
13 __tablename__ = 'abilities'
14 id = Column(Integer, primary_key=True, nullable=False)
15 name = Column(Unicode(24), nullable=False)
16 flavor_text = Column(Unicode(64), nullable=False)
17 effect = Column(Unicode(255), nullable=False)
18
19 class ContestEffect(TableBase):
20 __tablename__ = 'contest_effects'
21 id = Column(Integer, primary_key=True, nullable=False)
22 appeal = Column(SmallInteger, nullable=False)
23 jam = Column(SmallInteger, nullable=False)
24 flavor = Column(Unicode(255), nullable=False)
25 effect = Column(Unicode(255), nullable=False)
26
27 class EggGroup(TableBase):
28 __tablename__ = 'egg_groups'
29 id = Column(Integer, primary_key=True, nullable=False)
30 name = Column(Unicode(16), nullable=False)
31
32 class Encounter(TableBase):
33 """Rows in this table represent encounters with wild Pokémon.
34
35 Within a given area in a given game, encounters are differentiated by the
36 slot they are in and a world condition.
37
38 Groups of slots belong to encounter types; these are what the player is
39 doing to get an encounter, such as surfing or walking through tall grass.
40
41 Within an encounter type, slots are defined primarily by rarity. Each slot
42 can also be affected by a world condition; for example, the 20% slot for
43 walking in tall grass is affected by whether a swarm is in effect in the
44 areas. "There is a swarm" and "there is not a swarm" are conditions, and
45 together they make a condition group. However, since "not a swarm" is a
46 base state rather than any sort of new state, it is omitted and instead
47 referred to by a NULL.
48
49 A slot (20% walking in grass) and single world condition (NULL, i.e. no
50 swarm) are thus enough to define a specific encounter.
51
52 Well, okay, almost: each slot actually appears twice.
53 """
54
55 __tablename__ = 'encounters'
56 id = Column(Integer, primary_key=True, nullable=False)
57 version_id = Column(Integer, ForeignKey('versions.id'), nullable=False, autoincrement=False)
58 location_area_id = Column(Integer, ForeignKey('location_areas.id'), nullable=False, autoincrement=False)
59 encounter_type_slot_id = Column(Integer, ForeignKey('encounter_type_slots.id'), nullable=False, autoincrement=False)
60 encounter_condition_id = Column(Integer, ForeignKey('encounter_conditions.id'), nullable=True, autoincrement=False)
61 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), nullable=False, autoincrement=False)
62 min_level = Column(Integer, nullable=False, autoincrement=False)
63 max_level = Column(Integer, nullable=False, autoincrement=False)
64
65 class EncounterCondition(TableBase):
66 """Rows in this table represent something different about the world that
67 can affect what Pokémon are encountered.
68 """
69
70 __tablename__ = 'encounter_conditions'
71 id = Column(Integer, primary_key=True, nullable=False)
72 encounter_condition_group_id = Column(Integer, ForeignKey('encounter_condition_groups.id'), primary_key=False, nullable=False, autoincrement=False)
73 name = Column(Unicode(64), nullable=False)
74
75 class EncounterConditionGroup(TableBase):
76 """Rows in this table represent a group of mutually exclusive conditions,
77 such as morning/day/night. "Conditions" that are part of the default state
78 of the world, such as "not during a swarm" or "not using the PokéRadar",
79 are not included in this table and are referred to by NULLs in other
80 tables.
81 """
82
83 __tablename__ = 'encounter_condition_groups'
84 id = Column(Integer, primary_key=True, nullable=False)
85 name = Column(Unicode(64), nullable=False)
86
87 class EncounterType(TableBase):
88 """Rows in this table represent ways the player can enter a wild encounter;
89 i.e. surfing, fishing, or walking through tall grass.
90 """
91
92 __tablename__ = 'encounter_types'
93 id = Column(Integer, primary_key=True, nullable=False)
94 name = Column(Unicode(64), nullable=False)
95
96 class EncounterTypeSlot(TableBase):
97 """Rows in this table represent an abstract "slot" within an encounter
98 type, associated with both a condition group and a rarity.
99
100 Note that there are two encounters per slot, so the rarities will only add
101 up to 50.
102 """
103
104 __tablename__ = 'encounter_type_slots'
105 id = Column(Integer, primary_key=True, nullable=False)
106 encounter_type_id = Column(Integer, ForeignKey('encounter_types.id'), primary_key=False, nullable=False, autoincrement=False)
107 encounter_condition_group_id = Column(Integer, ForeignKey('encounter_condition_groups.id'), primary_key=False, nullable=True, autoincrement=False)
108 rarity = Column(Integer, nullable=False, autoincrement=False)
109
110 class EvolutionChain(TableBase):
111 __tablename__ = 'evolution_chains'
112 id = Column(Integer, primary_key=True, nullable=False)
113 growth_rate_id = Column(Integer, ForeignKey('growth_rates.id'), nullable=False)
114 steps_to_hatch = Column(Integer, nullable=False)
115 baby_trigger_item = Column(Unicode(12))
116
117 class EvolutionMethod(TableBase):
118 __tablename__ = 'evolution_methods'
119 id = Column(Integer, primary_key=True, nullable=False)
120 name = Column(Unicode(64), nullable=False)
121 description = Column(Unicode(255), nullable=False)
122
123 class Generation(TableBase):
124 __tablename__ = 'generations'
125 id = Column(Integer, primary_key=True, nullable=False)
126 name = Column(Unicode(16), nullable=False)
127 main_region = Column(Unicode(16), nullable=False)
128
129 class GrowthRate(TableBase):
130 __tablename__ = 'growth_rates'
131 id = Column(Integer, primary_key=True, nullable=False)
132 name = Column(Unicode(16), nullable=False)
133 formula = Column(Unicode(255), nullable=False)
134
135 class Language(TableBase):
136 __tablename__ = 'languages'
137 id = Column(Integer, primary_key=True, nullable=False)
138 name = Column(Unicode(16), nullable=False)
139
140 class Location(TableBase):
141 __tablename__ = 'locations'
142 id = Column(Integer, primary_key=True, nullable=False)
143 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
144 name = Column(Unicode(64), nullable=False)
145
146 class LocationArea(TableBase):
147 __tablename__ = 'location_areas'
148 id = Column(Integer, primary_key=True, nullable=False)
149 location_id = Column(Integer, ForeignKey('locations.id'), nullable=False)
150 internal_id = Column(Integer, nullable=False)
151 name = Column(Unicode(64), nullable=True)
152
153 class MoveEffect(TableBase):
154 __tablename__ = 'move_effects'
155 id = Column(Integer, primary_key=True, nullable=False)
156 priority = Column(SmallInteger, nullable=False)
157 short_effect = Column(Unicode(128), nullable=False)
158 effect = Column(Unicode(255), nullable=False)
159
160 class MoveTarget(TableBase):
161 __tablename__ = 'move_targets'
162 id = Column(Integer, primary_key=True, nullable=False)
163 name = Column(Unicode(32), nullable=False)
164 description = Column(Unicode(128), nullable=False)
165
166 class Move(TableBase):
167 __tablename__ = 'moves'
168 id = Column(Integer, primary_key=True, nullable=False)
169 name = Column(Unicode(12), nullable=False)
170 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
171 power = Column(SmallInteger)
172 pp = Column(SmallInteger, nullable=False)
173 accuracy = Column(SmallInteger)
174 target_id = Column(Integer, ForeignKey('move_targets.id'), nullable=False)
175 category = Column(Unicode(8), nullable=False)
176 effect_id = Column(Integer, ForeignKey('move_effects.id'), nullable=False)
177 effect_chance = Column(Integer)
178 contest_type = Column(Unicode(8), nullable=False)
179 contest_effect_id = Column(Integer, ForeignKey('contest_effects.id'), nullable=False)
180 super_contest_effect_id = Column(Integer, nullable=False)
181
182 class Pokemon(TableBase):
183 __tablename__ = 'pokemon'
184 id = Column(Integer, primary_key=True, nullable=False)
185 name = Column(Unicode(20), nullable=False)
186 forme_name = Column(Unicode(16))
187 forme_base_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
188 generation_id = Column(Integer, ForeignKey('generations.id'))
189 evolution_chain_id = Column(Integer, ForeignKey('evolution_chains.id'))
190 evolution_parent_pokemon_id = Column(Integer, ForeignKey('pokemon.id'))
191 evolution_method_id = Column(Integer, ForeignKey('evolution_methods.id'))
192 evolution_parameter = Column(Unicode(32))
193 height = Column(Integer, nullable=False)
194 weight = Column(Integer, nullable=False)
195 species = Column(Unicode(16), nullable=False)
196 color = Column(Unicode(6), nullable=False)
197 pokemon_shape_id = Column(Integer, ForeignKey('pokemon_shapes.id'), nullable=False)
198 habitat = Column(Unicode(16), nullable=False)
199 gender_rate = Column(Integer, nullable=False)
200 capture_rate = Column(Integer, nullable=False)
201 base_experience = Column(Integer, nullable=False)
202 base_happiness = Column(Integer, nullable=False)
203 gen1_internal_id = Column(Integer)
204 is_baby = Column(Boolean, nullable=False)
205 has_gen4_fem_sprite = Column(Boolean, nullable=False)
206 has_gen4_fem_back_sprite = Column(Boolean, nullable=False)
207
208 class PokemonAbility(TableBase):
209 __tablename__ = 'pokemon_abilities'
210 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
211 ability_id = Column(Integer, ForeignKey('abilities.id'), nullable=False)
212 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
213
214 class PokemonDexNumber(TableBase):
215 __tablename__ = 'pokemon_dex_numbers'
216 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
217 generation_id = Column(Integer, ForeignKey('generations.id'), primary_key=True, nullable=False, autoincrement=False)
218 pokedex_number = Column(Integer, nullable=False)
219
220 class PokemonEggGroup(TableBase):
221 __tablename__ = 'pokemon_egg_groups'
222 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
223 egg_group_id = Column(Integer, ForeignKey('egg_groups.id'), primary_key=True, nullable=False, autoincrement=False)
224
225 class PokemonFlavorText(TableBase):
226 __tablename__ = 'pokemon_flavor_text'
227 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
228 version_id = Column(Integer, ForeignKey('versions.id'), primary_key=True, nullable=False, autoincrement=False)
229 flavor_text = Column(Unicode(255), nullable=False)
230
231 class PokemonName(TableBase):
232 __tablename__ = 'pokemon_names'
233 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
234 language_id = Column(Integer, ForeignKey('languages.id'), primary_key=True, nullable=False, autoincrement=False)
235 name = Column(Unicode(16), nullable=False)
236
237 class PokemonShape(TableBase):
238 __tablename__ = 'pokemon_shapes'
239 id = Column(Integer, primary_key=True, nullable=False)
240 name = Column(Unicode(24), nullable=False)
241 awesome_name = Column(Unicode(16), nullable=False)
242
243 class PokemonStat(TableBase):
244 __tablename__ = 'pokemon_stats'
245 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
246 stat_id = Column(Integer, ForeignKey('stats.id'), primary_key=True, nullable=False, autoincrement=False)
247 base_stat = Column(Integer, nullable=False)
248 effort = Column(Integer, nullable=False)
249
250 class PokemonType(TableBase):
251 __tablename__ = 'pokemon_types'
252 pokemon_id = Column(Integer, ForeignKey('pokemon.id'), primary_key=True, nullable=False, autoincrement=False)
253 type_id = Column(Integer, ForeignKey('types.id'), nullable=False)
254 slot = Column(Integer, primary_key=True, nullable=False, autoincrement=False)
255
256 class Stat(TableBase):
257 __tablename__ = 'stats'
258 id = Column(Integer, primary_key=True, nullable=False)
259 name = Column(Unicode(16), nullable=False)
260
261 class TypeEfficacy(TableBase):
262 __tablename__ = 'type_efficacy'
263 damage_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
264 target_type_id = Column(Integer, ForeignKey('types.id'), primary_key=True, nullable=False, autoincrement=False)
265 damage_factor = Column(Integer, nullable=False)
266
267 class Type(TableBase):
268 __tablename__ = 'types'
269 id = Column(Integer, primary_key=True, nullable=False)
270 name = Column(Unicode(8), nullable=False)
271 abbreviation = Column(Unicode(3), nullable=False)
272
273 class VersionGroup(TableBase):
274 __tablename__ = 'version_groups'
275 id = Column(Integer, primary_key=True, nullable=False)
276 generation_id = Column(Integer, ForeignKey('generations.id'), nullable=False)
277
278 class Version(TableBase):
279 __tablename__ = 'versions'
280 id = Column(Integer, primary_key=True, nullable=False)
281 version_group_id = Column(Integer, ForeignKey('version_groups.id'), nullable=False)
282 name = Column(Unicode(32), nullable=False)
283
284
285 ### Relations down here, to avoid ordering problems
286 Encounter.pokemon = relation(Pokemon, backref='encounters')
287 Encounter.version = relation(Version, backref='encounters')
288 Encounter.location_area = relation(LocationArea, backref='encounters')
289 Encounter.slot = relation(EncounterTypeSlot, backref='encounters')
290 Encounter.condition = relation(EncounterCondition, backref='encounters')
291
292 EncounterCondition.group = relation(EncounterConditionGroup,
293 backref='conditions')
294
295 EncounterTypeSlot.type = relation(EncounterType, backref='slots')
296
297 EvolutionChain.growth_rate = relation(GrowthRate, backref='evolution_chains')
298
299 LocationArea.location = relation(Location, backref='areas')
300
301 Pokemon.abilities = relation(Ability, secondary=PokemonAbility.__table__,
302 order_by=PokemonAbility.slot,
303 backref='pokemon')
304 Pokemon.dex_numbers = relation(PokemonDexNumber, backref='pokemon')
305 Pokemon.egg_groups = relation(EggGroup, secondary=PokemonEggGroup.__table__,
306 order_by=PokemonEggGroup.egg_group_id,
307 backref='pokemon')
308 Pokemon.evolution_chain = relation(EvolutionChain, backref='pokemon')
309 Pokemon.evolution_method = relation(EvolutionMethod)
310 Pokemon.evolution_children = relation(Pokemon, primaryjoin=Pokemon.id==Pokemon.evolution_parent_pokemon_id,
311 backref=backref('evolution_parent',
312 remote_side=[Pokemon.id]))
313 Pokemon.flavor_text = relation(PokemonFlavorText, backref='pokemon')
314 Pokemon.foreign_names = relation(PokemonName, backref='pokemon')
315 Pokemon.generation = relation(Generation, backref='pokemon')
316 Pokemon.shape = relation(PokemonShape, backref='pokemon')
317 Pokemon.stats = relation(PokemonStat, backref='pokemon')
318 Pokemon.types = relation(Type, secondary=PokemonType.__table__)
319
320 PokemonDexNumber.generation = relation(Generation)
321
322 PokemonFlavorText.version = relation(Version)
323
324 PokemonName.language = relation(Language)
325
326 PokemonStat.stat = relation(Stat)
327
328 Type.damage_efficacies = relation(TypeEfficacy,
329 primaryjoin=Type.id
330 ==TypeEfficacy.damage_type_id,
331 backref='damage_type')
332 Type.target_efficacies = relation(TypeEfficacy,
333 primaryjoin=Type.id
334 ==TypeEfficacy.target_type_id,
335 backref='target_type')
336
337 Version.generation = relation(Generation, secondary=VersionGroup.__table__,
338 backref='versions')