Create scoped gamedata sessions

This commit is contained in:
DarkPhoenix
2020-04-16 15:01:00 +03:00
parent d830a8957a
commit 32db3e3179
2 changed files with 55 additions and 47 deletions

View File

@@ -21,7 +21,7 @@ import re
import threading
from sqlalchemy import MetaData, create_engine, event
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import sessionmaker, scoped_session
from . import migration
from eos import config
@@ -63,7 +63,15 @@ def create_functions(dbapi_connection, connection_record):
gamedata_meta = MetaData()
gamedata_meta.bind = gamedata_engine
gamedata_session = sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False)()
GamedataSession = scoped_session(sessionmaker(bind=gamedata_engine, autoflush=False, expire_on_commit=False))
gamedata_session = GamedataSession()
gamedata_sessions = {}
def get_gamedata_session():
thread_id = threading.get_ident()
if thread_id not in gamedata_sessions:
gamedata_sessions[thread_id] = GamedataSession()
return gamedata_sessions[thread_id]
pyfalog.debug('Getting gamedata version')
# This should be moved elsewhere, maybe as an actual query. Current, without try-except, it breaks when making a new

View File

@@ -22,7 +22,7 @@ from sqlalchemy.orm import aliased, exc, join
from sqlalchemy.sql import and_, or_, select
import eos.config
from eos.db import gamedata_session
from eos.db import get_gamedata_session
from eos.db.gamedata.item import items_table
from eos.db.gamedata.group import groups_table
from eos.db.util import processEager, processWhere
@@ -79,19 +79,19 @@ itemNameMap = {}
def getItem(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
item = gamedata_session.query(Item).get(lookfor)
item = get_gamedata_session().query(Item).get(lookfor)
else:
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
item = get_gamedata_session().query(Item).options(*processEager(eager)).filter(Item.ID == lookfor).first()
elif isinstance(lookfor, str):
if lookfor in itemNameMap:
id = itemNameMap[lookfor]
if eager is None:
item = gamedata_session.query(Item).get(id)
item = get_gamedata_session().query(Item).get(id)
else:
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.ID == id).first()
item = get_gamedata_session().query(Item).options(*processEager(eager)).filter(Item.ID == id).first()
else:
# Item names are unique, so we can use first() instead of one()
item = gamedata_session.query(Item).options(*processEager(eager)).filter(Item.name == lookfor).first()
item = get_gamedata_session().query(Item).options(*processEager(eager)).filter(Item.name == lookfor).first()
if item is not None:
itemNameMap[lookfor] = item.ID
else:
@@ -101,7 +101,7 @@ def getItem(lookfor, eager=None):
def getMutaplasmid(lookfor, eager=None):
if isinstance(lookfor, int):
item = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == lookfor).first()
item = get_gamedata_session().query(DynamicItem).filter(DynamicItem.ID == lookfor).first()
else:
raise TypeError("Need integer as argument")
return item
@@ -109,7 +109,7 @@ def getMutaplasmid(lookfor, eager=None):
def getItemWithBaseItemAttribute(lookfor, baseItemID, eager=None):
# A lot of this is described in more detail in #1597
item = gamedata_session.query(Item).get(lookfor)
item = get_gamedata_session().query(Item).get(lookfor)
base = getItem(baseItemID)
# we have to load all attributes for this object, otherwise we'll lose access to them when we expunge.
@@ -125,7 +125,7 @@ def getItemWithBaseItemAttribute(lookfor, baseItemID, eager=None):
# Expunge the item form the session. This is required to have different Abyssal / Base combinations loaded in memory.
# Without expunging it, once one Abyssal Web is created, SQLAlchmey will use it for all others. We don't want this,
# we want to generate a completely new object to work with
gamedata_session.expunge(item)
get_gamedata_session().expunge(item)
return item
@@ -148,7 +148,7 @@ def getItems(lookfor, eager=None):
if len(toGet) > 0:
# Get items that aren't currently cached, and store them in the cache
items = gamedata_session.query(Item).filter(Item.ID.in_(toGet)).all()
items = get_gamedata_session().query(Item).filter(Item.ID.in_(toGet)).all()
for item in items:
cache[(item.ID, None)] = item
results += items
@@ -162,9 +162,9 @@ def getItems(lookfor, eager=None):
def getAlphaClone(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
item = gamedata_session.query(AlphaClone).get(lookfor)
item = get_gamedata_session().query(AlphaClone).get(lookfor)
else:
item = gamedata_session.query(AlphaClone).options(*processEager(eager)).filter(AlphaClone.ID == lookfor).first()
item = get_gamedata_session().query(AlphaClone).options(*processEager(eager)).filter(AlphaClone.ID == lookfor).first()
else:
raise TypeError("Need integer as argument")
return item
@@ -172,7 +172,7 @@ def getAlphaClone(lookfor, eager=None):
def getAlphaCloneList(eager=None):
eager = processEager(eager)
clones = gamedata_session.query(AlphaClone).options(*eager).all()
clones = get_gamedata_session().query(AlphaClone).options(*eager).all()
return clones
@@ -183,19 +183,19 @@ groupNameMap = {}
def getGroup(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
group = gamedata_session.query(Group).get(lookfor)
group = get_gamedata_session().query(Group).get(lookfor)
else:
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
group = get_gamedata_session().query(Group).options(*processEager(eager)).filter(Group.ID == lookfor).first()
elif isinstance(lookfor, str):
if lookfor in groupNameMap:
id = groupNameMap[lookfor]
if eager is None:
group = gamedata_session.query(Group).get(id)
group = get_gamedata_session().query(Group).get(id)
else:
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.ID == id).first()
group = get_gamedata_session().query(Group).options(*processEager(eager)).filter(Group.ID == id).first()
else:
# Group names are unique, so we can use first() instead of one()
group = gamedata_session.query(Group).options(*processEager(eager)).filter(Group.name == lookfor).first()
group = get_gamedata_session().query(Group).options(*processEager(eager)).filter(Group.name == lookfor).first()
if group is not None:
groupNameMap[lookfor] = group.ID
else:
@@ -210,21 +210,21 @@ categoryNameMap = {}
def getCategory(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
category = gamedata_session.query(Category).get(lookfor)
category = get_gamedata_session().query(Category).get(lookfor)
else:
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
category = get_gamedata_session().query(Category).options(*processEager(eager)).filter(
Category.ID == lookfor).first()
elif isinstance(lookfor, str):
if lookfor in categoryNameMap:
id = categoryNameMap[lookfor]
if eager is None:
category = gamedata_session.query(Category).get(id)
category = get_gamedata_session().query(Category).get(id)
else:
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
category = get_gamedata_session().query(Category).options(*processEager(eager)).filter(
Category.ID == id).first()
else:
# Category names are unique, so we can use first() instead of one()
category = gamedata_session.query(Category).options(*processEager(eager)).filter(
category = get_gamedata_session().query(Category).options(*processEager(eager)).filter(
Category.name == lookfor).first()
if category is not None:
categoryNameMap[lookfor] = category.ID
@@ -240,21 +240,21 @@ metaGroupNameMap = {}
def getMetaGroup(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
metaGroup = gamedata_session.query(MetaGroup).get(lookfor)
metaGroup = get_gamedata_session().query(MetaGroup).get(lookfor)
else:
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
metaGroup = get_gamedata_session().query(MetaGroup).options(*processEager(eager)).filter(
MetaGroup.ID == lookfor).first()
elif isinstance(lookfor, str):
if lookfor in metaGroupNameMap:
id = metaGroupNameMap[lookfor]
if eager is None:
metaGroup = gamedata_session.query(MetaGroup).get(id)
metaGroup = get_gamedata_session().query(MetaGroup).get(id)
else:
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
metaGroup = get_gamedata_session().query(MetaGroup).options(*processEager(eager)).filter(
MetaGroup.ID == id).first()
else:
# MetaGroup names are unique, so we can use first() instead of one()
metaGroup = gamedata_session.query(MetaGroup).options(*processEager(eager)).filter(
metaGroup = get_gamedata_session().query(MetaGroup).options(*processEager(eager)).filter(
MetaGroup.name == lookfor).first()
if metaGroup is not None:
metaGroupNameMap[lookfor] = metaGroup.ID
@@ -264,16 +264,16 @@ def getMetaGroup(lookfor, eager=None):
def getMetaGroups():
return gamedata_session.query(MetaGroup).all()
return get_gamedata_session().query(MetaGroup).all()
@cachedQuery(1, "lookfor")
def getMarketGroup(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
marketGroup = gamedata_session.query(MarketGroup).get(lookfor)
marketGroup = get_gamedata_session().query(MarketGroup).get(lookfor)
else:
marketGroup = gamedata_session.query(MarketGroup).options(*processEager(eager)).filter(
marketGroup = get_gamedata_session().query(MarketGroup).options(*processEager(eager)).filter(
MarketGroup.ID == lookfor).first()
else:
raise TypeError("Need integer as argument")
@@ -285,7 +285,7 @@ def getMarketTreeNodeIds(rootNodeIds):
addedIds = set(rootNodeIds)
while addedIds:
allIds.update(addedIds)
addedIds = {mg.ID for mg in gamedata_session.query(MarketGroup).filter(MarketGroup.parentGroupID.in_(addedIds))}
addedIds = {mg.ID for mg in get_gamedata_session().query(MarketGroup).filter(MarketGroup.parentGroupID.in_(addedIds))}
return allIds
@@ -299,7 +299,7 @@ def getItemsByCategory(filter, where=None, eager=None):
raise TypeError("Need integer or string as argument")
filter = processWhere(filter, where)
return gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category).filter(
return get_gamedata_session().query(Item).options(*processEager(eager)).join(Item.group, Group.category).filter(
filter).all()
@@ -314,7 +314,7 @@ def searchItems(nameLike, where=None, join=None, eager=None):
if not hasattr(join, "__iter__"):
join = (join,)
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
items = get_gamedata_session().query(Item).options(*processEager(eager)).join(*join)
for token in nameLike.split(' '):
token_safe = "%{0}%".format(sqlizeNormalString(token))
if where is not None:
@@ -336,7 +336,7 @@ def searchItemsRegex(tokens, where=None, join=None, eager=None):
if not hasattr(join, "__iter__"):
join = (join,)
items = gamedata_session.query(Item).options(*processEager(eager)).join(*join)
items = get_gamedata_session().query(Item).options(*processEager(eager)).join(*join)
for token in tokens:
if where is not None:
items = items.filter(and_(Item.name.op('regexp')(token), where))
@@ -351,7 +351,7 @@ def searchSkills(nameLike, where=None, eager=None):
if not isinstance(nameLike, str):
raise TypeError("Need string as argument")
items = gamedata_session.query(Item).options(*processEager(eager)).join(Item.group, Group.category)
items = get_gamedata_session().query(Item).options(*processEager(eager)).join(Item.group, Group.category)
for token in nameLike.split(' '):
token_safe = "%{0}%".format(sqlizeNormalString(token))
if where is not None:
@@ -373,7 +373,7 @@ def getVariations(itemids, groupIDs=None, where=None, eager=None):
itemfilter = or_(*(items_table.c.variationParentTypeID == itemid for itemid in itemids))
filter = processWhere(itemfilter, where)
vars = gamedata_session.query(Item).options(*processEager(eager)).filter(filter).all()
vars = get_gamedata_session().query(Item).options(*processEager(eager)).filter(filter).all()
if vars:
return vars
@@ -381,7 +381,7 @@ def getVariations(itemids, groupIDs=None, where=None, eager=None):
itemfilter = or_(*(groups_table.c.groupID == groupID for groupID in groupIDs))
filter = processWhere(itemfilter, where)
joinon = items_table.c.groupID == groups_table.c.groupID
vars = gamedata_session.query(Item).options(*processEager(eager)).join((groups_table, joinon)).filter(
vars = get_gamedata_session().query(Item).options(*processEager(eager)).join((groups_table, joinon)).filter(
filter).all()
return vars
@@ -396,7 +396,7 @@ def getAttributeInfo(attr, eager=None):
else:
raise TypeError("Need integer or string as argument")
try:
result = gamedata_session.query(AttributeInfo).options(*processEager(eager)).filter(filter).one()
result = get_gamedata_session().query(AttributeInfo).options(*processEager(eager)).filter(filter).one()
except exc.NoResultFound:
result = None
return result
@@ -405,7 +405,7 @@ def getAttributeInfo(attr, eager=None):
@cachedQuery(1, "field")
def getMetaData(field):
if isinstance(field, str):
data = gamedata_session.query(MetaData).get(field)
data = get_gamedata_session().query(MetaData).get(field)
else:
raise TypeError("Need string as argument")
return data
@@ -424,12 +424,12 @@ def directAttributeRequest(itemIDs, attrIDs):
and_(Attribute.attributeID.in_(attrIDs), Item.typeID.in_(itemIDs)),
from_obj=[join(Attribute, Item)])
result = gamedata_session.execute(q).fetchall()
result = get_gamedata_session().execute(q).fetchall()
return result
def getAbyssalTypes():
return set([r.resultingTypeID for r in gamedata_session.query(DynamicItem.resultingTypeID).distinct()])
return set([r.resultingTypeID for r in get_gamedata_session().query(DynamicItem.resultingTypeID).distinct()])
@cachedQuery(1, "itemID")
@@ -437,9 +437,9 @@ def getDynamicItem(itemID, eager=None):
try:
if isinstance(itemID, int):
if eager is None:
result = gamedata_session.query(DynamicItem).filter(DynamicItem.ID == itemID).one()
result = get_gamedata_session().query(DynamicItem).filter(DynamicItem.ID == itemID).one()
else:
result = gamedata_session.query(DynamicItem).options(*processEager(eager)).filter(DynamicItem.ID == itemID).one()
result = get_gamedata_session().query(DynamicItem).options(*processEager(eager)).filter(DynamicItem.ID == itemID).one()
else:
raise TypeError("Need integer as argument")
except exc.NoResultFound:
@@ -449,5 +449,5 @@ def getDynamicItem(itemID, eager=None):
@cachedQuery(1, "lookfor")
def getAllImplantSets():
implantSets = gamedata_session.query(ImplantSet).all()
implantSets = get_gamedata_session().query(ImplantSet).all()
return implantSets