Skip to content

Commit 6f9a022

Browse files
Merge pull request #889 from guzman-raphael/adjustments
Minor adjustments for release
2 parents 88d5db2 + 51f55ab commit 6f9a022

22 files changed

+160
-24
lines changed

.coveragerc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ branch = False
33
source = datajoint
44

55
[report]
6+
show_missing = True

.github/workflows/development.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
- name: Run primary tests
3737
env:
3838
UID: "1001"
39-
GID: "116"
39+
GID: "121"
4040
PY_VER: ${{matrix.py_ver}}
4141
MYSQL_VER: ${{matrix.mysql_ver}}
4242
ALPINE_VER: "3.10"

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,14 @@
1212
* Bugfix - Regression error on joins with same attribute name (#857) PR #878
1313
* Bugfix - Error when `fetch1('KEY')` when `dj.config['fetch_format']='frame'` set (#876) PR #880, #878
1414
* Bugfix - Error when cascading deletes in tables with many, complex keys (#883, #886) PR #839
15+
* Add deprecation warning for `_update`. PR #889
16+
* Add `purge_query_cache` utility. PR #889
17+
* Add tests for query caching and permissive join and restriction. PR #889
1518
* Drop support for Python 3.5
1619

20+
### 0.12.9 -- Mar 12, 2021
21+
* Fix bug with fetch1 with `dj.config['fetch_format']="frame"`. (#876) PR #880
22+
1723
### 0.12.8 -- Jan 12, 2021
1824
* table.children, .parents, .descendents, and ancestors can return queryable objects. PR #833
1925
* Load dependencies before querying dependencies. (#179) PR #833

LNX-docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# docker-compose -f LNX-docker-compose.yml --env-file LNX.env up --build --exit-code-from app
1+
# docker-compose -f LNX-docker-compose.yml --env-file LNX.env up --exit-code-from app --build
22
version: '2.2'
33
x-net: &net
44
networks:
@@ -78,7 +78,7 @@ services:
7878
- |
7979
set -e
8080
pip install --user -r test_requirements.txt
81-
pip install --user .
81+
pip install -e .
8282
pip freeze | grep datajoint
8383
nosetests -vsw tests --with-coverage --cover-package=datajoint
8484
coveralls

datajoint/condition.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ def prep_value(k, v):
8484
try:
8585
v = uuid.UUID(v)
8686
except (AttributeError, ValueError):
87-
raise DataJointError('Badly formed UUID {v} in restriction by `{k}`'.format(k=k, v=v)) from None
87+
raise DataJointError(
88+
'Badly formed UUID {v} in restriction by `{k}`'.format(k=k, v=v))
8889
return "X'%s'" % v.bytes.hex()
8990
if isinstance(v, (datetime.date, datetime.datetime, datetime.time, decimal.Decimal)):
9091
return '"%s"' % v

datajoint/connection.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ def connect(self):
218218
k == 'ssl' and self.conn_info['ssl_input'] is None)})
219219
self._conn.autocommit(True)
220220

221-
def set_query_cache(self, query_cache):
221+
def set_query_cache(self, query_cache=None):
222222
"""
223223
When query_cache is not None, the connection switches into the query caching mode, which entails:
224224
1. Only SELECT queries are allowed.
@@ -228,6 +228,14 @@ def set_query_cache(self, query_cache):
228228
"""
229229
self._query_cache = query_cache
230230

231+
def purge_query_cache(self):
232+
""" Purges all query cache. """
233+
if 'query_cache' in config and isinstance(config['query_cache'], str) and \
234+
pathlib.Path(config['query_cache']).is_dir():
235+
path_iter = pathlib.Path(config['query_cache']).glob('**/*')
236+
for path in path_iter:
237+
path.unlink()
238+
231239
def close(self):
232240
self._conn.close()
233241

datajoint/expression.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,15 @@ def restrict_in_place(self, restriction):
193193

194194
def __and__(self, restriction):
195195
"""
196-
Restriction operator
196+
Restriction operator e.g. q1 & q2.
197197
:return: a restricted copy of the input argument
198198
See QueryExpression.restrict for more detail.
199199
"""
200200
return self.restrict(restriction)
201201

202202
def __xor__(self, restriction):
203203
"""
204-
Restriction operator ignoring compatibility check.
204+
Permissive restriction operator ignoring compatibility check e.g. q1 ^ q2.
205205
"""
206206
if inspect.isclass(restriction) and issubclass(restriction, QueryExpression):
207207
restriction = restriction()
@@ -211,22 +211,33 @@ def __xor__(self, restriction):
211211

212212
def __sub__(self, restriction):
213213
"""
214-
Inverted restriction
214+
Inverted restriction e.g. q1 - q2.
215215
:return: a restricted copy of the input argument
216216
See QueryExpression.restrict for more detail.
217217
"""
218218
return self.restrict(Not(restriction))
219219

220220
def __neg__(self):
221+
"""
222+
Convert between restriction and inverted restriction e.g. -q1.
223+
:return: target restriction
224+
See QueryExpression.restrict for more detail.
225+
"""
221226
if isinstance(self, Not):
222227
return self.restriction
223228
return Not(self)
224229

225230
def __mul__(self, other):
226-
""" join of query expressions `self` and `other` """
231+
"""
232+
join of query expressions `self` and `other` e.g. q1 * q2.
233+
"""
227234
return self.join(other)
228235

229236
def __matmul__(self, other):
237+
"""
238+
Permissive join of query expressions `self` and `other` ignoring compatibility check
239+
e.g. q1 @ q2.
240+
"""
230241
if inspect.isclass(other) and issubclass(other, QueryExpression):
231242
other = other() # instantiate
232243
return self.join(other, semantic_check=False)
@@ -271,7 +282,7 @@ def join(self, other, semantic_check=True, left=False):
271282
return result
272283

273284
def __add__(self, other):
274-
"""union"""
285+
"""union e.g. q1 + q2."""
275286
return Union.create(self, other)
276287

277288
def proj(self, *attributes, **named_attributes):
@@ -424,7 +435,7 @@ def tail(self, limit=25, **fetch_kwargs):
424435
return self.fetch(order_by="KEY DESC", limit=limit, **fetch_kwargs)[::-1]
425436

426437
def __len__(self):
427-
""" :return: number of elements in the result set """
438+
""":return: number of elements in the result set e.g. len(q1)."""
428439
return self.connection.query(
429440
'SELECT count(DISTINCT {fields}) FROM {from_}{where}'.format(
430441
fields=self.heading.as_sql(self.primary_key, include_aliases=False),
@@ -433,7 +444,8 @@ def __len__(self):
433444

434445
def __bool__(self):
435446
"""
436-
:return: True if the result is not empty. Equivalent to len(self) > 0 but often faster.
447+
:return: True if the result is not empty. Equivalent to len(self) > 0 but often
448+
faster e.g. bool(q1).
437449
"""
438450
return bool(self.connection.query(
439451
'SELECT EXISTS(SELECT 1 FROM {from_}{where})'.format(
@@ -442,19 +454,30 @@ def __bool__(self):
442454

443455
def __contains__(self, item):
444456
"""
445-
returns True if item is found in the .
457+
returns True if a restriction results with any records e.g. restriction in q1.
446458
:param item: any restriction
447459
(item in query_expression) is equivalent to bool(query_expression & item) but may be
448460
executed more efficiently.
449461
"""
450462
return bool(self & item) # May be optimized e.g. using an EXISTS query
451463

452464
def __iter__(self):
465+
"""
466+
returns an iterator-compatible QueryExpression object e.g. iter(q1).
467+
468+
:param self: iterator-compatible QueryExpression object
469+
"""
453470
self._iter_only_key = all(v.in_key for v in self.heading.attributes.values())
454471
self._iter_keys = self.fetch('KEY')
455472
return self
456473

457474
def __next__(self):
475+
"""
476+
returns the next record on an iterator-compatible QueryExpression object
477+
e.g. next(q1).
478+
479+
:param self: fetch1 record
480+
"""
458481
try:
459482
key = self._iter_keys.pop(0)
460483
except AttributeError:
@@ -490,6 +513,11 @@ def cursor(self, offset=0, limit=None, order_by=None, as_dict=False):
490513
return self.connection.query(sql, as_dict=as_dict)
491514

492515
def __repr__(self):
516+
"""
517+
returns the string representation of a QueryExpression object e.g. str(q1).
518+
519+
:param self: String version of query result
520+
"""
493521
return super().__repr__() if config['loglevel'].lower() == 'debug' else self.preview()
494522

495523
def preview(self, limit=None, width=None):

datajoint/table.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import logging
88
import uuid
99
import re
10+
import warnings
1011
from pathlib import Path
1112
from .settings import config
1213
from .declare import declare, alter
@@ -568,6 +569,9 @@ def _update(self, attrname, value=None):
568569
>>> (v2p.Mice() & key)._update('mouse_dob', '2011-01-01')
569570
>>> (v2p.Mice() & key)._update( 'lens') # set the value to NULL
570571
"""
572+
warnings.warn(
573+
'`_update` is a deprecated function to be removed in datajoint 0.14. '
574+
'Use `.update1` instead.')
571575
if len(self) != 1:
572576
raise DataJointError('Update is only allowed on one tuple at a time')
573577
if attrname not in self.heading:

datajoint/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
__version__ = "0.13.dev7"
1+
__version__ = "0.13.0"
22

33
assert len(__version__) <= 10 # The log table limits version to the 10 characters

docs-parts/computation/01-autopopulate_lang1.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"""
1212
1313
def make(self, key):
14-
img = (test.Image & key).fetch1['image']
14+
img = (test.Image & key).fetch1('image')
1515
key['filtered_image'] = myfilter(img)
1616
self.insert(key)
1717

0 commit comments

Comments
 (0)