diff --git a/pokedex/data/csv/pokemon_dex_numbers.csv b/pokedex/data/csv/pokemon_dex_numbers.csv index ccf26c8..02c50de 100644 --- a/pokedex/data/csv/pokemon_dex_numbers.csv +++ b/pokedex/data/csv/pokemon_dex_numbers.csv @@ -3084,7 +3084,7 @@ species_id,pokedex_id,pokedex_number 407,5,27 407,6,27 407,9,135 -407,12,72 +407,12,73 407,15,99 408,1,408 408,5,36 diff --git a/pokedex/db/tables.py b/pokedex/db/tables.py index cd0ded1..0c2aa39 100644 --- a/pokedex/db/tables.py +++ b/pokedex/db/tables.py @@ -1771,6 +1771,13 @@ class PokemonDexNumber(TableBase): pokedex_number = Column(Integer, nullable=False, doc=u"Number of the Pokémon in that the Pokédex") + __table_args__ = ( + UniqueConstraint(pokedex_id, pokedex_number), + UniqueConstraint(pokedex_id, species_id), + {}, + ) + + class PokemonEggGroup(TableBase): u"""Maps an Egg group to a species; each species belongs to one or two egg groups.""" __tablename__ = 'pokemon_egg_groups' diff --git a/pokedex/tests/test_database_sanity.py b/pokedex/tests/test_database_sanity.py index ff9b73b..c515a48 100644 --- a/pokedex/tests/test_database_sanity.py +++ b/pokedex/tests/test_database_sanity.py @@ -1,6 +1,7 @@ import pytest parametrize = pytest.mark.parametrize +from collections import Counter import re from sqlalchemy.orm import aliased, joinedload, lazyload @@ -69,7 +70,7 @@ def test_nonzero_autoincrement_ids(session, cls): pytest.fail("No zero id in %s" % cls.__name__) def test_unique_form_order(session): - """Check that tone PokemonForm.order value isn't used for more species""" + """Check that one PokemonForm.order value isn't used for more species""" species_by_form_order = {} @@ -88,6 +89,22 @@ def test_unique_form_order(session): species_by_form_order[form.order].name, form.species.name)) +def test_pokedex_numbers(session): + """Check that pokedex numbers are contiguous (there are no gaps)""" + + dex_query = session.query(tables.Pokedex).order_by(tables.Pokedex.id) + failed = False + for dex in dex_query: + query = session.query(tables.PokemonDexNumber.pokedex_number).filter_by(pokedex_id=dex.id) + numbers = set([x[0] for x in query.all()]) + for i in range(1, max(numbers)): + if i not in numbers: + print("number {n} is missing from the {dex.name} pokedex".format(n=i, dex=dex)) + failed = True + + assert not failed, "missing pokedex numbers" + + def test_default_forms(session): """Check that each pokemon has one default form and each species has one default pokemon."""