Skip to content

Commit 84cfb19

Browse files
committed
cache related tables, find recent surveys
1 parent 6066205 commit 84cfb19

File tree

2 files changed

+88
-13
lines changed

2 files changed

+88
-13
lines changed

agolutils/arcgis/survey123.py

Lines changed: 84 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pandas
88

99

10-
from agolutils.utils import make_path
10+
from agolutils.utils import make_path, yesterday, tomorrow
1111
from agolutils.context import write_context
1212
from .utils import get_content
1313

@@ -89,7 +89,7 @@ def download_all_attachments(
8989

9090
def get_layer_records_by_objectid(layer, oids: List[int]):
9191
object_ids = ",".join(map(str, oids))
92-
q = layer.query(object_ids=object_ids)
92+
q = layer.query(object_ids=object_ids, return_geometry=False)
9393
df = q.sdf
9494
return json.loads(df.to_json(orient="records"))
9595

@@ -99,13 +99,27 @@ def get_layer_by_prop(service, prop, equals):
9999
return next(filter(fxn, service.layers + service.tables))
100100

101101

102-
def get_related_records(service, layer, oid, context_dir, download_attachments=True):
103-
relates = {}
104-
102+
def get_related_tables(service, layer):
103+
tables = []
105104
for relationship in layer.properties.relationships:
106105
rel_id = relationship["id"]
107106
tableid = relationship["relatedTableId"]
108107
table = get_layer_by_prop(service, "id", tableid)
108+
tables.append({"rel_id": rel_id, "table": table})
109+
return tables
110+
111+
112+
def get_related_records(
113+
layer, oid, context_dir, service=None, tables=None, download_attachments=True
114+
):
115+
relates = {}
116+
117+
if tables is None:
118+
tables = get_related_tables(service, layer)
119+
120+
for rel in tables:
121+
rel_id = rel["rel_id"]
122+
table = rel["table"]
109123
name = table.properties.name
110124

111125
related_record_groups = layer.query_related_records(oid, rel_id).get(
@@ -138,7 +152,9 @@ def get_related_records(service, layer, oid, context_dir, download_attachments=T
138152
]
139153
)
140154

141-
rel_df = table.query(object_ids=",".join(map(str, rel_oids))).sdf
155+
rel_df = table.query(
156+
object_ids=",".join(map(str, rel_oids)), return_geometry=False
157+
).sdf
142158
if files:
143159
rel_df = rel_df.merge(pandas.DataFrame(files), on="objectid")
144160

@@ -166,12 +182,13 @@ def slim_layer_properties(props: dict):
166182

167183

168184
def get_contexts(
169-
service,
170185
layer,
171186
oids,
172187
context_file_pattern=None,
173188
download_attachments=True,
174189
get_relates=True,
190+
tables=None,
191+
service=None,
175192
):
176193
records = get_layer_records_by_objectid(layer, oids)
177194
if context_file_pattern is None:
@@ -192,11 +209,12 @@ def get_contexts(
192209

193210
if get_relates:
194211
context["relates"] = get_related_records(
195-
service,
196212
layer,
197213
oid,
198-
download_attachments=download_attachments,
199214
context_dir=outdir,
215+
tables=tables,
216+
service=service,
217+
download_attachments=download_attachments,
200218
)
201219

202220
if download_attachments and layer.properties.hasAttachments:
@@ -206,7 +224,7 @@ def get_contexts(
206224
layer,
207225
oid=oid,
208226
attachment_id=att["id"],
209-
save_path=outdir,
227+
save_path=str(outdir),
210228
filename_prefix=context["_layer_name"] + "-",
211229
)
212230

@@ -218,22 +236,74 @@ def get_contexts(
218236
return contexts
219237

220238

239+
def get_recent(layer, related_tables=None, start_date=None, end_date=None):
240+
if related_tables is None:
241+
related_tables = []
242+
if start_date is None:
243+
start_date = yesterday()
244+
if end_date is None:
245+
end_date = tomorrow()
246+
247+
time_query = (
248+
f"EditDate >= TIMESTAMP '{start_date}' and EditDate <= TIMESTAMP '{end_date}'"
249+
)
250+
251+
globalids = None
252+
253+
if related_tables:
254+
dfs = []
255+
for t in related_tables:
256+
sdf = (
257+
t["table"]
258+
.query(time_query, out_fields=["parentglobalid"], return_geometry=False)
259+
.sdf
260+
)
261+
if not sdf.empty:
262+
dfs.extend(sdf["parentglobalid"].unique())
263+
recent_surveys = set(dfs)
264+
globalids = ", ".join([f"'{x}'" for x in recent_surveys])
265+
266+
q = f"({time_query})"
267+
if globalids:
268+
q += f"or (globalid in ({globalids}))"
269+
270+
sdf = layer.query(q, out_fields=["objectid"], return_geometry=False).sdf
271+
272+
return [] if sdf.empty else sdf["objectid"].to_list()
273+
274+
221275
class Survey123Service:
222276
def __init__(self, item: arcgis.gis.Item):
223277
self.service = item
224278

225279
self._survey_layer = None
226280
self._survey_properties = None
227-
self._tables = None
281+
self._related_tables = None
228282

229283
@property
230284
def survey_layer(self):
231285
if self._survey_layer is None:
232286
self._survey_layer = self.service.layers[0]
233287
return self._survey_layer
234288

289+
@property
290+
def related_tables(self):
291+
if self._related_tables is None:
292+
self._related_tables = get_related_tables(self.service, self.survey_layer)
293+
return self._related_tables
294+
295+
def get_recent(self, start_date=None, end_date=None):
296+
return get_recent(
297+
self.survey_layer,
298+
related_tables=self.related_tables,
299+
start_date=start_date,
300+
end_date=end_date,
301+
)
302+
235303
def get_related_records(self, oid, context_dir):
236-
return get_related_records(self.service, self.survey_layer, oid, context_dir)
304+
return get_related_records(
305+
self.survey_layer, oid, context_dir, tables=self.related_tables
306+
)
237307

238308
def get_contexts(
239309
self,
@@ -243,9 +313,10 @@ def get_contexts(
243313
get_relates=True,
244314
):
245315
return get_contexts(
246-
self.service,
247316
self.survey_layer,
248317
oids,
318+
tables=self.related_tables,
319+
service=self.service,
249320
context_file_pattern=context_file_pattern,
250321
download_attachments=download_attachments,
251322
get_relates=get_relates,

agolutils/utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,7 @@ def format_date(timestamp, tz_string=None, fmt=None):
9292

9393
else:
9494
return utc_dt
95+
96+
97+
tomorrow = lambda : (datetime.datetime.utcnow() + datetime.timedelta(1)).strftime("%Y-%m-%d")
98+
yesterday = lambda : (datetime.datetime.utcnow() - datetime.timedelta(1)).strftime("%Y-%m-%d")

0 commit comments

Comments
 (0)