mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-21 05:45:37 +08:00
Merge pull request #5514 from jmchilton/optimize_public_grids
[18.01] Optimize public grid database interactions.
This commit is contained in:
@@ -1570,7 +1570,11 @@ mapper(model.History, model.History.table, properties=dict(
|
||||
backref="histories"),
|
||||
ratings=relation(model.HistoryRatingAssociation,
|
||||
order_by=model.HistoryRatingAssociation.table.c.id,
|
||||
backref="histories")
|
||||
backref="histories"),
|
||||
average_rating=column_property(
|
||||
select([func.avg(model.HistoryRatingAssociation.table.c.rating)]).where(model.HistoryRatingAssociation.table.c.history_id == model.History.table.c.id),
|
||||
deferred=True
|
||||
)
|
||||
))
|
||||
|
||||
# Set up proxy so that
|
||||
@@ -2184,7 +2188,11 @@ mapper(model.StoredWorkflow, model.StoredWorkflow.table, properties=dict(
|
||||
backref="stored_workflows"),
|
||||
ratings=relation(model.StoredWorkflowRatingAssociation,
|
||||
order_by=model.StoredWorkflowRatingAssociation.table.c.id,
|
||||
backref="stored_workflows")
|
||||
backref="stored_workflows"),
|
||||
average_rating=column_property(
|
||||
select([func.avg(model.StoredWorkflowRatingAssociation.table.c.rating)]).where(model.StoredWorkflowRatingAssociation.table.c.stored_workflow_id == model.StoredWorkflow.table.c.id),
|
||||
deferred=True
|
||||
)
|
||||
))
|
||||
|
||||
# Set up proxy so that
|
||||
@@ -2316,7 +2324,11 @@ mapper(model.Page, model.Page.table, properties=dict(
|
||||
backref="pages"),
|
||||
ratings=relation(model.PageRatingAssociation,
|
||||
order_by=model.PageRatingAssociation.table.c.id,
|
||||
backref="pages")
|
||||
backref="pages"),
|
||||
average_rating=column_property(
|
||||
select([func.avg(model.PageRatingAssociation.table.c.rating)]).where(model.PageRatingAssociation.table.c.page_id == model.Page.table.c.id),
|
||||
deferred=True
|
||||
)
|
||||
))
|
||||
|
||||
# Set up proxy so that
|
||||
@@ -2348,7 +2360,11 @@ mapper(model.Visualization, model.Visualization.table, properties=dict(
|
||||
backref="visualizations"),
|
||||
ratings=relation(model.VisualizationRatingAssociation,
|
||||
order_by=model.VisualizationRatingAssociation.table.c.id,
|
||||
backref="visualizations")
|
||||
backref="visualizations"),
|
||||
average_rating=column_property(
|
||||
select([func.avg(model.VisualizationRatingAssociation.table.c.rating)]).where(model.VisualizationRatingAssociation.table.c.visualization_id == model.Visualization.table.c.id),
|
||||
deferred=True
|
||||
)
|
||||
))
|
||||
|
||||
# Set up proxy so that
|
||||
|
||||
@@ -573,7 +573,12 @@ class CommunityRatingColumn(GridColumn, UsesItemRatings):
|
||||
""" Column that displays community ratings for an item. """
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
ave_item_rating, num_ratings = self.get_ave_item_rating_data(trans.sa_session, item, webapp_model=trans.model)
|
||||
if not hasattr(item, "average_rating"):
|
||||
# No prefetched column property, generate it on the fly.
|
||||
ave_item_rating, num_ratings = self.get_ave_item_rating_data(trans.sa_session, item, webapp_model=trans.model)
|
||||
else:
|
||||
ave_item_rating = item.average_rating
|
||||
num_ratings = 2 # just used for pluralization
|
||||
return trans.fill_template("tool_shed_rating.mako",
|
||||
ave_item_rating=ave_item_rating,
|
||||
num_ratings=num_ratings,
|
||||
|
||||
@@ -5,7 +5,7 @@ from markupsafe import escape
|
||||
from six import string_types
|
||||
from six.moves.urllib.parse import unquote_plus
|
||||
from sqlalchemy import and_, false, func, null, true
|
||||
from sqlalchemy.orm import eagerload, eagerload_all
|
||||
from sqlalchemy.orm import eagerload, eagerload_all, undefer
|
||||
|
||||
import galaxy.util
|
||||
from galaxy import exceptions
|
||||
@@ -209,8 +209,20 @@ class HistoryAllPublishedGrid(grids.Grid):
|
||||
operations = []
|
||||
|
||||
def build_initial_query(self, trans, **kwargs):
|
||||
# Join so that searching history.user makes sense.
|
||||
return trans.sa_session.query(self.model_class).join(model.User.table)
|
||||
# TODO: Tags are still loaded one at a time, consider doing this all at once:
|
||||
# - eagerload would keep everything in one query but would explode the number of rows and potentially
|
||||
# result in unneeded info transferred over the wire.
|
||||
# - subqueryload("tags").subqueryload("tag") would probably be better under postgres but I'd
|
||||
# like some performance data against a big database first - might cause problems?
|
||||
|
||||
# - Pull down only username from associated User table since that is all that is used
|
||||
# (can be used during search). Need join in addition to the eagerload since it is used in
|
||||
# the .count() query which doesn't respect the eagerload options (could eliminate this with #5523).
|
||||
# - Undefer average_rating column to prevent loading individual ratings per-history.
|
||||
# - Eager load annotations - this causes a left join which might be inefficient if there were
|
||||
# potentially many items per history (like if joining HDAs for instance) but there should only
|
||||
# be at most one so this is fine.
|
||||
return trans.sa_session.query(self.model_class).join("user").options(eagerload("user").load_only("username"), eagerload("annotations"), undefer("average_rating"))
|
||||
|
||||
def apply_query_filter(self, trans, query, **kwargs):
|
||||
# A public history is published, has a slug, and is not deleted.
|
||||
|
||||
@@ -2,6 +2,7 @@ from json import loads
|
||||
|
||||
from markupsafe import escape
|
||||
from sqlalchemy import and_, desc, false, true
|
||||
from sqlalchemy.orm import eagerload, undefer
|
||||
|
||||
from galaxy import managers, model, util, web
|
||||
from galaxy.model.item_attrs import UsesItemRatings
|
||||
@@ -82,8 +83,8 @@ class PageAllPublishedGrid(grids.Grid):
|
||||
)
|
||||
|
||||
def build_initial_query(self, trans, **kwargs):
|
||||
# Join so that searching history.user makes sense.
|
||||
return trans.sa_session.query(self.model_class).join(model.User.table)
|
||||
# See optimization description comments and TODO for tags in matching public histories query.
|
||||
return trans.sa_session.query(self.model_class).join("user").options(eagerload("user").load_only("username"), eagerload("annotations"), undefer("average_rating"))
|
||||
|
||||
def apply_query_filter(self, trans, query, **kwargs):
|
||||
return query.filter(self.model_class.deleted == false()).filter(self.model_class.published == true())
|
||||
|
||||
@@ -12,6 +12,7 @@ from paste.httpexceptions import (
|
||||
)
|
||||
from six import string_types
|
||||
from sqlalchemy import and_, desc, false, or_, true
|
||||
from sqlalchemy.orm import eagerload, undefer
|
||||
|
||||
from galaxy import managers, model, util, web
|
||||
from galaxy.datatypes.interval import Bed
|
||||
@@ -212,8 +213,8 @@ class VisualizationAllPublishedGrid(grids.Grid):
|
||||
)
|
||||
|
||||
def build_initial_query(self, trans, **kwargs):
|
||||
# Join so that searching history.user makes sense.
|
||||
return trans.sa_session.query(self.model_class).join(model.User.table)
|
||||
# See optimization description comments and TODO for tags in matching public histories query.
|
||||
return trans.sa_session.query(self.model_class).join("user").options(eagerload("user").load_only("username"), eagerload("annotations"), undefer("average_rating"))
|
||||
|
||||
def apply_query_filter(self, trans, query, **kwargs):
|
||||
return query.filter(self.model_class.deleted == false()).filter(self.model_class.published == true())
|
||||
|
||||
@@ -10,7 +10,7 @@ import requests
|
||||
from markupsafe import escape
|
||||
from six.moves.http_client import HTTPConnection
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.orm import eagerload, joinedload, lazyload, undefer
|
||||
from sqlalchemy.sql import expression
|
||||
|
||||
from galaxy import (
|
||||
@@ -138,8 +138,10 @@ class StoredWorkflowAllPublishedGrid(grids.Grid):
|
||||
]
|
||||
|
||||
def build_initial_query(self, trans, **kwargs):
|
||||
# Join so that searching stored_workflow.user makes sense.
|
||||
return trans.sa_session.query(self.model_class).join(model.User.table)
|
||||
# See optimization description comments and TODO for tags in matching public histories query.
|
||||
# In addition to that - be sure to lazyload the latest_workflow - it isn't needed and it causes all
|
||||
# of its steps to be eagerly loaded.
|
||||
return trans.sa_session.query(self.model_class).join("user").options(lazyload("latest_workflow"), eagerload("user").load_only("username"), eagerload("annotations"), undefer("average_rating"))
|
||||
|
||||
def apply_query_filter(self, trans, query, **kwargs):
|
||||
# A public workflow is published, has a slug, and is not deleted.
|
||||
|
||||
Reference in New Issue
Block a user