mirror of
https://github.com/veekun/pokedex.git
synced 2024-08-20 18:16:34 +00:00
Merge 678f9f8e94
into cc483e1877
This commit is contained in:
commit
da44e19652
4 changed files with 52 additions and 24 deletions
|
@ -17,7 +17,7 @@ from pokedex.defaults import get_default_csv_dir
|
||||||
from pokedex.db.dependencies import find_dependent_tables
|
from pokedex.db.dependencies import find_dependent_tables
|
||||||
from pokedex.db.oracle import rewrite_long_table_names
|
from pokedex.db.oracle import rewrite_long_table_names
|
||||||
|
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_, true
|
||||||
from sqlalchemy.sql import exists
|
from sqlalchemy.sql import exists
|
||||||
|
|
||||||
|
|
||||||
|
@ -381,6 +381,7 @@ def load(session, tables=[], directory=None, drop_tables=False, verbose=False, s
|
||||||
session.query(VGPMM).delete()
|
session.query(VGPMM).delete()
|
||||||
|
|
||||||
q = session.query(t.VersionGroup.id, t.PokemonMoveMethod.id)
|
q = session.query(t.VersionGroup.id, t.PokemonMoveMethod.id)
|
||||||
|
q = q.filter(true()) # Suppress cartesian product warning
|
||||||
q = q.filter(exists().where(and_(
|
q = q.filter(exists().where(and_(
|
||||||
t.PokemonMove.pokemon_move_method_id == t.PokemonMoveMethod.id,
|
t.PokemonMove.pokemon_move_method_id == t.PokemonMoveMethod.id,
|
||||||
t.PokemonMove.version_group_id == t.VersionGroup.id)))
|
t.PokemonMove.version_group_id == t.VersionGroup.id)))
|
||||||
|
|
|
@ -10,6 +10,18 @@ from sqlalchemy.types import Integer
|
||||||
|
|
||||||
from pokedex.db import markdown
|
from pokedex.db import markdown
|
||||||
|
|
||||||
|
# Decide which method to use for the default value of the parameter _default_language_id
|
||||||
|
_MULTILANG_SESSION_USE_EVENT = False
|
||||||
|
try:
|
||||||
|
from sqlalchemy.orm import SessionEvents
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if hasattr(SessionEvents, 'do_orm_execute'):
|
||||||
|
# SQLAlchemy 1.4+
|
||||||
|
from sqlalchemy import event
|
||||||
|
_MULTILANG_SESSION_USE_EVENT = True
|
||||||
|
|
||||||
class LocalAssociationProxy(AssociationProxy, ColumnOperators):
|
class LocalAssociationProxy(AssociationProxy, ColumnOperators):
|
||||||
"""An association proxy for names in the default language
|
"""An association proxy for names in the default language
|
||||||
|
|
||||||
|
@ -168,11 +180,12 @@ def create_translation_table(_table_name, foreign_class, relation_name,
|
||||||
primaryjoin=and_(
|
primaryjoin=and_(
|
||||||
Translations.foreign_id == foreign_class.id,
|
Translations.foreign_id == foreign_class.id,
|
||||||
Translations.local_language_id == bindparam('_default_language_id',
|
Translations.local_language_id == bindparam('_default_language_id',
|
||||||
value='dummy', type_=Integer, required=True),
|
value='dummy', type_=Integer),
|
||||||
),
|
),
|
||||||
foreign_keys=[Translations.foreign_id, Translations.local_language_id],
|
foreign_keys=[Translations.foreign_id, Translations.local_language_id],
|
||||||
uselist=False,
|
uselist=False,
|
||||||
lazy=relation_lazy,
|
lazy=relation_lazy,
|
||||||
|
viewonly=True,
|
||||||
))
|
))
|
||||||
|
|
||||||
# Add per-column proxies to the original class
|
# Add per-column proxies to the original class
|
||||||
|
@ -206,14 +219,16 @@ def create_translation_table(_table_name, foreign_class, relation_name,
|
||||||
# Done
|
# Done
|
||||||
return Translations
|
return Translations
|
||||||
|
|
||||||
class MultilangQuery(Query):
|
if not _MULTILANG_SESSION_USE_EVENT:
|
||||||
def _execute_and_instances(self, *args, **kwargs):
|
# SQLAlchemy 1.4 no longer supports Query._execute_and_instances
|
||||||
# Set _default_language_id param if it hasn't been set by the time the query is executed.
|
class MultilangQuery(Query):
|
||||||
# XXX This is really hacky and we should figure out a cleaner method.
|
def _execute_and_instances(self, *args, **kwargs):
|
||||||
if '_default_language_id' not in self._params or self._params['_default_language_id'] == 'dummy':
|
# Set _default_language_id param if it hasn't been set by the time the query is executed.
|
||||||
self._params = self._params.copy()
|
# XXX This is really hacky and we should figure out a cleaner method.
|
||||||
self._params['_default_language_id'] = self.session.default_language_id
|
if '_default_language_id' not in self._params or self._params['_default_language_id'] == 'dummy':
|
||||||
return super(MultilangQuery, self)._execute_and_instances(*args, **kwargs)
|
self._params = self._params.copy()
|
||||||
|
self._params['_default_language_id'] = self.session.default_language_id
|
||||||
|
return super(MultilangQuery, self)._execute_and_instances(*args, **kwargs)
|
||||||
|
|
||||||
class MultilangSession(Session):
|
class MultilangSession(Session):
|
||||||
"""A tiny Session subclass that adds support for a default language.
|
"""A tiny Session subclass that adds support for a default language.
|
||||||
|
@ -232,10 +247,19 @@ class MultilangSession(Session):
|
||||||
|
|
||||||
self.markdown_extension = markdown_extension_class(self)
|
self.markdown_extension = markdown_extension_class(self)
|
||||||
|
|
||||||
kwargs.setdefault('query_cls', MultilangQuery)
|
if not _MULTILANG_SESSION_USE_EVENT:
|
||||||
|
kwargs.setdefault('query_cls', MultilangQuery)
|
||||||
|
|
||||||
super(MultilangSession, self).__init__(*args, **kwargs)
|
super(MultilangSession, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
if _MULTILANG_SESSION_USE_EVENT:
|
||||||
|
@event.listens_for(MultilangSession, 'do_orm_execute')
|
||||||
|
def receive_do_orm_execute(state):
|
||||||
|
# Set _default_language_id param if it hasn't been set by the time the query is executed.
|
||||||
|
# The same hack as above, but for SQLAlchemy 1.4+
|
||||||
|
if state.is_select and state.parameters.get('_default_language_id', 'dummy') == 'dummy':
|
||||||
|
return state.invoke_statement(params={'_default_language_id': state.session.default_language_id})
|
||||||
|
|
||||||
class MultilangScopedSession(ScopedSession):
|
class MultilangScopedSession(ScopedSession):
|
||||||
"""Dispatches language selection to the attached Session."""
|
"""Dispatches language selection to the attached Session."""
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ from functools import partial
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from sqlalchemy import Column, ForeignKey, MetaData, PrimaryKeyConstraint, UniqueConstraint
|
from sqlalchemy import Column, ForeignKey, MetaData, PrimaryKeyConstraint, UniqueConstraint
|
||||||
|
from sqlalchemy import __version__ as sqla_version
|
||||||
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
|
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
|
||||||
from sqlalchemy.ext.associationproxy import association_proxy
|
from sqlalchemy.ext.associationproxy import association_proxy
|
||||||
from sqlalchemy.ext.hybrid import hybrid_property
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
|
@ -39,6 +40,12 @@ from sqlalchemy.types import Boolean, Enum, Integer, SmallInteger, Unicode, Unic
|
||||||
|
|
||||||
from pokedex.db import markdown, multilang
|
from pokedex.db import markdown, multilang
|
||||||
|
|
||||||
|
relationship = partial(relationship, viewonly=True)
|
||||||
|
if (1, 3, 17) <= tuple(int(x) for x in sqla_version.split(".")) < (1, 4):
|
||||||
|
# `sync_backref` was introduced in 1.3.17
|
||||||
|
# Since 1.4 it defaults to False if `viewonly` is True
|
||||||
|
relationship = partial(relationship, sync_backref=False)
|
||||||
|
|
||||||
class TableSuperclass(object):
|
class TableSuperclass(object):
|
||||||
"""Superclass for declarative tables, to give them some generic niceties
|
"""Superclass for declarative tables, to give them some generic niceties
|
||||||
like stringification.
|
like stringification.
|
||||||
|
@ -2475,7 +2482,8 @@ Experience.growth_rate = relationship(GrowthRate,
|
||||||
Generation.versions = relationship(Version,
|
Generation.versions = relationship(Version,
|
||||||
secondary=VersionGroup.__table__,
|
secondary=VersionGroup.__table__,
|
||||||
innerjoin=True)
|
innerjoin=True)
|
||||||
Generation.main_region = relationship(Region, innerjoin=True)
|
Generation.main_region = relationship(Region, innerjoin=True,
|
||||||
|
backref=backref('generation', uselist=False))
|
||||||
|
|
||||||
|
|
||||||
GrowthRate.max_experience_obj = relationship(Experience,
|
GrowthRate.max_experience_obj = relationship(Experience,
|
||||||
|
@ -2497,14 +2505,13 @@ Item.flavor_text = relationship(ItemFlavorText,
|
||||||
Item.fling_effect = relationship(ItemFlingEffect,
|
Item.fling_effect = relationship(ItemFlingEffect,
|
||||||
backref='items')
|
backref='items')
|
||||||
Item.machines = relationship(Machine,
|
Item.machines = relationship(Machine,
|
||||||
order_by=Machine.version_group_id.asc())
|
order_by=Machine.version_group_id.asc(),
|
||||||
|
backref='item')
|
||||||
Item.category = relationship(ItemCategory,
|
Item.category = relationship(ItemCategory,
|
||||||
innerjoin=True,
|
innerjoin=True,
|
||||||
backref=backref('items', order_by=Item.identifier.asc()))
|
backref=backref('items', order_by=Item.identifier.asc()))
|
||||||
Item.pocket = association_proxy('category', 'pocket')
|
Item.pocket = association_proxy('category', 'pocket')
|
||||||
|
|
||||||
ItemCategory.pocket = relationship(ItemPocket, innerjoin=True)
|
|
||||||
|
|
||||||
ItemFlavorText.version_group = relationship(VersionGroup,
|
ItemFlavorText.version_group = relationship(VersionGroup,
|
||||||
innerjoin=True, lazy='joined')
|
innerjoin=True, lazy='joined')
|
||||||
ItemFlavorText.language = relationship(Language,
|
ItemFlavorText.language = relationship(Language,
|
||||||
|
@ -2518,7 +2525,8 @@ ItemGameIndex.generation = relationship(Generation,
|
||||||
|
|
||||||
ItemPocket.categories = relationship(ItemCategory,
|
ItemPocket.categories = relationship(ItemCategory,
|
||||||
innerjoin=True,
|
innerjoin=True,
|
||||||
order_by=ItemCategory.identifier.asc())
|
order_by=ItemCategory.identifier.asc(),
|
||||||
|
backref=backref('pocket', innerjoin=True))
|
||||||
|
|
||||||
|
|
||||||
Location.region = relationship(Region,
|
Location.region = relationship(Region,
|
||||||
|
@ -2542,11 +2550,6 @@ LocationGameIndex.generation = relationship(Generation,
|
||||||
innerjoin=True, lazy='joined')
|
innerjoin=True, lazy='joined')
|
||||||
|
|
||||||
|
|
||||||
Machine.item = relationship(Item)
|
|
||||||
Machine.version_group = relationship(VersionGroup,
|
|
||||||
innerjoin=True, lazy='joined')
|
|
||||||
|
|
||||||
|
|
||||||
Move.changelog = relationship(MoveChangelog,
|
Move.changelog = relationship(MoveChangelog,
|
||||||
order_by=MoveChangelog.changed_in_version_group_id.desc(),
|
order_by=MoveChangelog.changed_in_version_group_id.desc(),
|
||||||
backref=backref('move', innerjoin=True, lazy='joined'))
|
backref=backref('move', innerjoin=True, lazy='joined'))
|
||||||
|
@ -2886,7 +2889,6 @@ PokemonSpecies.conquest_evolution = relationship(ConquestPokemonEvolution,
|
||||||
PokemonSpeciesFlavorText.version = relationship(Version, innerjoin=True, lazy='joined')
|
PokemonSpeciesFlavorText.version = relationship(Version, innerjoin=True, lazy='joined')
|
||||||
PokemonSpeciesFlavorText.language = relationship(Language, innerjoin=True, lazy='joined')
|
PokemonSpeciesFlavorText.language = relationship(Language, innerjoin=True, lazy='joined')
|
||||||
|
|
||||||
Region.generation = relationship(Generation, uselist=False)
|
|
||||||
Region.version_group_regions = relationship(VersionGroupRegion,
|
Region.version_group_regions = relationship(VersionGroupRegion,
|
||||||
order_by=VersionGroupRegion.version_group_id.asc(),
|
order_by=VersionGroupRegion.version_group_id.asc(),
|
||||||
backref='region')
|
backref='region')
|
||||||
|
@ -2950,7 +2952,8 @@ VersionGroup.pokemon_move_methods = relationship(PokemonMoveMethod,
|
||||||
backref="version_groups")
|
backref="version_groups")
|
||||||
VersionGroup.machines = relationship(Machine,
|
VersionGroup.machines = relationship(Machine,
|
||||||
innerjoin=True,
|
innerjoin=True,
|
||||||
order_by=Machine.machine_number)
|
order_by=Machine.machine_number,
|
||||||
|
backref=backref('version_group', innerjoin=True, lazy='joined'))
|
||||||
|
|
||||||
|
|
||||||
VersionGroupPokemonMoveMethod.version_group = relationship(VersionGroup,
|
VersionGroupPokemonMoveMethod.version_group = relationship(VersionGroup,
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -9,7 +9,7 @@ setup(
|
||||||
'pokedex': ['data/csv/*.csv']
|
'pokedex': ['data/csv/*.csv']
|
||||||
},
|
},
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'SQLAlchemy>=1.0,<1.4',
|
'SQLAlchemy>=1.0,<2.0',
|
||||||
'whoosh>=2.5,<2.7',
|
'whoosh>=2.5,<2.7',
|
||||||
'markdown>=2.4.1,<=2.6.11',
|
'markdown>=2.4.1,<=2.6.11',
|
||||||
'construct==2.5.3',
|
'construct==2.5.3',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue