-
Notifications
You must be signed in to change notification settings - Fork 90
Attachments and configurable blobs #532
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
Changes from 1 commit
5918b2c
bc85f21
92553b0
c127693
1b188da
13573c5
f3dd5b3
046291a
1f5fe9d
3350516
acc07fb
c11bbbf
390b0b7
2c04d74
43e9c76
51336ff
cee588e
c04f974
9de4782
0c35af1
1588303
f265674
bcebce5
50f17ce
f141aa7
6310c7d
7cb1d3f
aa72832
4818bbb
3aa936e
bdf8195
173bf1d
61c2ce7
aa6a2ce
f49cf22
eea3e20
7ee6134
6701abb
346f47f
b2087aa
332cfd6
0c491e2
7e51e4f
0434fc8
484e926
1a83fe6
4c8b6eb
bf66d64
8f4e8f9
0826d94
fb14029
90cf697
afeadb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| """ | ||
| a schema for testing external attributes using legacy syntax pre-version 0.12.0 | ||
| """ | ||
|
|
||
| import tempfile | ||
| import datajoint as dj | ||
|
|
||
| from . import PREFIX, CONN_INFO | ||
| import numpy as np | ||
|
|
||
| schema = dj.schema(PREFIX + '_legacy_extern', connection=dj.conn(**CONN_INFO)) | ||
|
|
||
|
|
||
| dj.config['external'] = { | ||
| 'protocol': 'file', | ||
| 'location': 'dj-legacy/external'} | ||
|
|
||
| dj.config['external-raw'] = { | ||
| 'protocol': 'file', | ||
| 'location': 'dj-legacy/raw'} | ||
|
|
||
| dj.config['external-compute'] = { | ||
| 'protocol': 's3', | ||
| 'location': '/datajoint-legacy/test', | ||
| 'user': 'djtest', | ||
| 'token': '2e05709792545ce'} | ||
|
|
||
| dj.config['cache'] = tempfile.mkdtemp('dj-legacy-cache') | ||
|
|
||
|
|
||
| @schema | ||
| class Simple(dj.Manual): | ||
| definition = """ | ||
| simple : int | ||
| --- | ||
| item : external-raw | ||
| """ | ||
|
|
||
|
|
||
| @schema | ||
| class Seed(dj.Lookup): | ||
| definition = """ | ||
| seed : int | ||
| """ | ||
| contents = zip(range(4)) | ||
|
|
||
|
|
||
| @schema | ||
| class Dimension(dj.Lookup): | ||
| definition = """ | ||
| dim : int | ||
| --- | ||
| dimensions : blob | ||
| """ | ||
| contents = ( | ||
| [0, [100, 50]], | ||
| [1, [3, 4, 8, 6]]) | ||
|
|
||
|
|
||
| @schema | ||
| class Image(dj.Computed): | ||
| definition = """ | ||
| # table for storing | ||
| -> Seed | ||
| -> Dimension | ||
| ---- | ||
| img : external-raw # objects are stored as specified by dj.config['external-raw'] | ||
| neg : external # objects are stored as specified by dj.config['external'] | ||
| """ | ||
|
|
||
| def make(self, key): | ||
| np.random.seed(key['seed']) | ||
| img = np.random.rand(*(Dimension() & key).fetch1('dimensions')) | ||
| self.insert1(dict(key, img=img, neg=-img.astype(np.float32))) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import numpy as np | ||
| from numpy.testing import assert_array_equal | ||
| from nose.tools import assert_true, assert_equal | ||
| from datajoint.external import ExternalTable | ||
| from datajoint.blob import pack, unpack | ||
|
|
||
| from . schema_legacy_external import schema | ||
|
|
||
|
|
||
| def test_external_put(): | ||
| """ | ||
| external storage put and get and remove | ||
| """ | ||
| ext = ExternalTable(schema.connection, schema.database) | ||
| input_ = np.random.randn(3, 7, 8) | ||
| count = 7 | ||
| extra = 3 | ||
| for i in range(count): | ||
| hash1 = ext.put('external-raw', pack(input_)) | ||
| for i in range(extra): | ||
| hash2 = ext.put('external-raw', pack(np.random.randn(4, 3, 2))) | ||
|
|
||
| fetched_hashes = ext.fetch('hash') | ||
| assert_true(all(hash in fetched_hashes for hash in (hash1, hash2))) | ||
| assert_equal(len(ext), 1 + extra) | ||
|
|
||
| output_ = unpack(ext.get(hash1)) | ||
| assert_array_equal(input_, output_) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| from nose.tools import assert_true, assert_list_equal, raises | ||
| from numpy.testing import assert_almost_equal | ||
| import datajoint as dj | ||
| from . import schema_legacy_external as modu | ||
|
|
||
|
|
||
| def test_heading(): | ||
| heading = modu.Simple().heading | ||
| assert_true('item' in heading) | ||
| assert_true(heading['item'].is_external) | ||
|
|
||
|
|
||
| def test_insert_and_fetch(): | ||
| original_list = [1, 3, 8] | ||
| modu.Simple().insert1(dict(simple=1, item=original_list)) | ||
|
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. Same as above; should the 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. This is inside legacy tests. We support both syntaxes. |
||
| # test fetch | ||
| q = (modu.Simple() & {'simple': 1}).fetch('item')[0] | ||
| assert_list_equal(list(q), original_list) | ||
| # test fetch1 as a tuple | ||
| q = (modu.Simple() & {'simple': 1}).fetch1('item') | ||
| assert_list_equal(list(q), original_list) | ||
| # test fetch1 as a dict | ||
| q = (modu.Simple() & {'simple': 1}).fetch1() | ||
| assert_list_equal(list(q['item']), original_list) | ||
| # test without cache | ||
| previous_cache = dj.config['cache'] | ||
| dj.config['cache'] = None | ||
| q = (modu.Simple() & {'simple': 1}).fetch1() | ||
| assert_list_equal(list(q['item']), original_list) | ||
| # test with cache | ||
| dj.config['cache'] = previous_cache | ||
| q = (modu.Simple() & {'simple': 1}).fetch1() | ||
| assert_list_equal(list(q['item']), original_list) | ||
|
|
||
|
|
||
| def test_populate(): | ||
| image = modu.Image() | ||
|
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. Can we remove these 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. Yes, we could but, when using the same table multiple times, it's more efficient to instantiate once. 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. This particular snippet is inside |
||
| image.populate() | ||
| remaining, total = image.progress() | ||
| image.external_table.clean_store('raw') | ||
| assert_true(total == len(modu.Dimension() * modu.Seed()) and remaining == 0) | ||
| for img, neg, dimensions in zip(*(image * modu.Dimension()).fetch('img', 'neg', 'dimensions')): | ||
| assert_list_equal(list(img.shape), list(dimensions)) | ||
| assert_almost_equal(img, -neg) | ||
| image.delete() | ||
| image.external_table.delete_garbage() | ||
| image.external_table.clean_store('raw') | ||
|
|
||
|
|
||
| @raises(dj.DataJointError) | ||
| def test_drop(): | ||
| image = modu.Image() | ||
| image.populate() | ||
| image.external_table.drop() | ||
|
|
||
|
|
||
| @raises(dj.DataJointError) | ||
| def test_delete(): | ||
| image = modu.Image() | ||
| image.external_table.delete() | ||
|
|
||
|
|
||
|
|
||
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.
You removed the
()in line 8 oftest_external_class.pyabove. Should you do so here as well?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.
This does not really matter. Accessing attributes of classes directly still triggers instantiation of an object, so a more efficient way is to instantiate. The omission of parentheses was provided for user convenience.