-
Notifications
You must be signed in to change notification settings - Fork 52
Export generalizations #1387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Export generalizations #1387
Changes from 3 commits
ded2544
2d57e64
02fb80c
f34a079
eab1f33
c809db7
342bc97
346f17a
e9d0b34
e9051a5
8d2929b
0363267
f6fe1d0
4dad0c2
cb03db4
8bf01ff
4f9dc92
78f3af5
3fef2b0
41d6177
3b958e6
e58f2bf
e6fca26
9947282
ac8ce65
11d7349
8dfe2c6
126a028
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -167,7 +167,7 @@ def _called_funcs(self): | |
| ret = {i.function for i in inspect_stack()} - ignore | ||
| return ret | ||
|
|
||
| def _log_fetch(self, restriction=None, *args, **kwargs): | ||
| def _log_fetch(self, restriction=None, chunk_size=None, *args, **kwargs): | ||
| """Log fetch for export.""" | ||
| if ( | ||
| not self.export_id | ||
|
|
@@ -203,20 +203,47 @@ def _log_fetch(self, restriction=None, *args, **kwargs): | |
| if restr_str is True: | ||
| restr_str = "True" # otherwise stored in table as '1' | ||
|
|
||
| if isinstance(restr_str, str) and "SELECT" in restr_str: | ||
| raise RuntimeError( | ||
| "Export cannot handle subquery restrictions. Please submit a " | ||
| + "bug report on GitHub with the code you ran and this" | ||
| + f"restriction:\n\t{restr_str}" | ||
| if not ( | ||
| ( | ||
| isinstance(restr_str, str) | ||
| and (len(restr_str) > 2048) | ||
| or "SELECT" in restr_str | ||
| ) | ||
| ): | ||
| self._insert_log(restr_str) | ||
| return | ||
|
|
||
| if isinstance(restr_str, str) and len(restr_str) > 2048: | ||
| raise RuntimeError( | ||
| "Export cannot handle restrictions > 2048.\n\t" | ||
| + "If required, please open an issue on GitHub.\n\t" | ||
| + f"Restriction: {restr_str}" | ||
| if "SELECT" in restr_str: | ||
| logger.debug( | ||
| "Restriction contains subquery. Exporting entry restrictions instead" | ||
samuelbray32 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ) | ||
|
|
||
| # handle excessive restrictions caused by long OR list of dicts | ||
| logger.debug( | ||
| f"Restriction too long ({len(restr_str)} > 2048)." | ||
| + "Attempting to chunk restriction by subsets of entry keys." | ||
| ) | ||
samuelbray32 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| # get list of entry keys | ||
| restricted_table = ( | ||
| self.restrict(restriction, log_export=False) | ||
| if restriction | ||
| else self | ||
|
Comment on lines
+279
to
+280
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have neither a passed restriction nor a |
||
| ) | ||
| restricted_entries = restricted_table.fetch("KEY", log_export=False) | ||
|
||
| if chunk_size is None: | ||
| # estimate appropriate chunk size | ||
| chunk_size = max( | ||
| int(2048 // (len(restr_str) / len(restricted_entries))), 1 | ||
|
||
| ) | ||
| for i in range(len(restricted_entries) // chunk_size + 1): | ||
| chunk_entries = restricted_entries[ | ||
| i * chunk_size : (i + 1) * chunk_size | ||
| ] | ||
| chunk_restr_str = make_condition(self, chunk_entries, set()) | ||
| self._insert_log(chunk_restr_str) | ||
|
||
| return | ||
|
|
||
| def _insert_log(self, restr_str): | ||
| if isinstance(restr_str, str): | ||
| restr_str = bash_escape_sql(restr_str, add_newline=False) | ||
|
|
||
|
|
@@ -292,10 +319,6 @@ def _run_with_log(self, method, *args, log_export=True, **kwargs): | |
| self._run_join(**kwargs) | ||
| else: | ||
| restr = kwargs.get("restriction") | ||
| if isinstance(restr, QueryExpression) and getattr( | ||
CBroz1 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| restr, "restriction" # if table, try to get restriction | ||
| ): | ||
| restr = restr.restriction | ||
| self._log_fetch(restriction=restr) | ||
| logger.debug(f"Export: {self._called_funcs()}") | ||
|
|
||
|
|
@@ -323,7 +346,7 @@ def fetch1(self, *args, log_export=True, **kwargs): | |
| super().fetch1, *args, log_export=log_export, **kwargs | ||
| ) | ||
|
|
||
| def restrict(self, restriction): | ||
| def restrict(self, restriction, chunk_size=10): | ||
samuelbray32 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """Log restrict for export.""" | ||
| if not self.export_id: | ||
| return super().restrict(restriction) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still possible we'll bump this
2048in the future. If so, it would be helpful to have a comment underExportSelection.Tablesaying this was hard-coded hereIt's also possible to fetch the value with
self._export_table.Table.heading.attributes['restriction'].type[8:-1], but I would want to save that as acached_propertylikeself._export_restr_limitin that case to prevent that kind of table definition fetch on each iteration.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll also add in a raised error in
_insert_logif too long a restriction makes it to there.