From adad27dadbe3fec932a53034c5a5be63d552f3bf Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Wed, 12 Aug 2020 09:34:13 +0100 Subject: [PATCH] Lazy load feature from the SQLite database MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rather than querying all the features whenever we look up area(s) let’s only get them when we need them. The features are really big blobs of data to pass around, so there’s a significant performance gain to be had from doing this. --- app/broadcast_areas/__init__.py | 24 ++++++++------------- app/broadcast_areas/repo.py | 38 +++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/app/broadcast_areas/__init__.py b/app/broadcast_areas/__init__.py index 800821357..5f4338578 100644 --- a/app/broadcast_areas/__init__.py +++ b/app/broadcast_areas/__init__.py @@ -29,25 +29,19 @@ class GetItemByIdMixin: class BroadcastArea(SortableMixin): def __init__(self, row): - id, name, feature, simple_feature = row - - self.id = id - self.name = name - - self._feature = feature - self._simple_feature = simple_feature - - for coordinates in self.polygons: - if coordinates[0] != coordinates[-1]: - # The CAP XML format requires shapes to be closed - raise ValueError( - f'Area {self.name} is not a closed shape ' - f'({coordinates[0]}, {coordinates[-1]})' - ) + self.id, self.name = row def __eq__(self, other): return self.id == other.id + @property + def _feature(self): + return BroadcastAreasRepository().get_feature_for_area(self.id) + + @property + def _simple_feature(self): + return BroadcastAreasRepository().get_simple_feature_for_area(self.id) + def _polygons(self, feature): if feature['geometry']['type'] == 'MultiPolygon': return [ diff --git a/app/broadcast_areas/repo.py b/app/broadcast_areas/repo.py index 3ded4d264..6851758b2 100644 --- a/app/broadcast_areas/repo.py +++ b/app/broadcast_areas/repo.py @@ -128,7 +128,7 @@ class BroadcastAreasRepository(object): cursor = conn.cursor() q = """ - SELECT id, name, feature_geojson, simple_feature_geojson + SELECT id, name FROM broadcast_areas WHERE id IN ({}) """.format(("?," * len(*area_ids))[:-1]) @@ -136,7 +136,7 @@ class BroadcastAreasRepository(object): results = cursor.fetchall() areas = [ - (row[0], row[1], row[2], row[3]) + (row[0], row[1]) for row in results ] @@ -144,7 +144,7 @@ class BroadcastAreasRepository(object): def get_all_areas_for_library(self, library_id): q = """ - SELECT id, name, feature_geojson, simple_feature_geojson + SELECT id, name FROM broadcast_areas WHERE broadcast_area_library_id = ? AND broadcast_area_library_group_id IS NULL @@ -152,16 +152,14 @@ class BroadcastAreasRepository(object): results = self.query(q, library_id) - areas = [ - (row[0], row[1], row[2], row[3]) + return [ + (row[0], row[1]) for row in results ] - return areas - def get_all_areas_for_group(self, group_id): q = """ - SELECT id, name, feature_geojson, simple_feature_geojson + SELECT id, name FROM broadcast_areas WHERE broadcast_area_library_group_id = ? """ @@ -169,7 +167,7 @@ class BroadcastAreasRepository(object): results = self.query(q, group_id) areas = [ - (row[0], row[1], row[2], row[3]) + (row[0], row[1]) for row in results ] @@ -191,3 +189,25 @@ class BroadcastAreasRepository(object): ] return areas + + def get_feature_for_area(self, area_id): + q = """ + SELECT feature_geojson + FROM broadcast_areas + WHERE id = ? + """ + + results = self.query(q, area_id) + + return results[0][0] + + def get_simple_feature_for_area(self, area_id): + q = """ + SELECT simple_feature_geojson + FROM broadcast_areas + WHERE id = ? + """ + + results = self.query(q, area_id) + + return results[0][0]