deriva 1.7.3__py3-none-any.whl → 1.7.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,782 @@
1
+ # Tests for the datapath module.
2
+ #
3
+ # Environment variables:
4
+ # DERIVA_PY_TEST_HOSTNAME: hostname of the test server
5
+ # DERIVA_PY_CATALOG: catalog identifier of the reusable test catalog (optional)
6
+ # DERIVA_PY_TEST_CREDENTIAL: user credential, if none, it will attempt to get credential for given hostname (optional)
7
+ # DERIVA_PY_TEST_VERBOSE: set for verbose logging output to stdout (optional)
8
+
9
+ import logging
10
+ import os
11
+ import unittest
12
+ from deriva.core import DerivaServer, get_credential, ermrest_model, tag
13
+
14
+ logger = logging.getLogger(__name__)
15
+ logger.addHandler(logging.StreamHandler())
16
+ if os.getenv("DERIVA_PY_TEST_VERBOSE"):
17
+ logger.setLevel(logging.DEBUG)
18
+ else:
19
+ logger.setLevel(logging.INFO)
20
+
21
+ hostname = os.getenv("DERIVA_PY_TEST_HOSTNAME")
22
+
23
+
24
+ @unittest.skipUnless(hostname, "Test host not specified")
25
+ class ErmrestModelTests (unittest.TestCase):
26
+
27
+ catalog = None
28
+
29
+ @classmethod
30
+ def _purgeCatalog(cls):
31
+ model = cls.catalog.getCatalogModel()
32
+
33
+ # exclude the 'public' schema
34
+ schemas = [s for s in model.schemas.values() if s.name != 'public']
35
+
36
+ # drop all fkeys
37
+ for s in schemas:
38
+ for t in s.tables.values():
39
+ for fk in list(t.foreign_keys):
40
+ fk.drop()
41
+
42
+ # drop all tables and schemas
43
+ for s in list(schemas):
44
+ for t in list(s.tables.values()):
45
+ t.drop()
46
+ s.drop()
47
+
48
+ @classmethod
49
+ def setUpClass(cls):
50
+ credential = os.getenv("DERIVA_PY_TEST_CREDENTIAL") or get_credential(hostname)
51
+ server = DerivaServer('https', hostname, credentials=credential)
52
+ catalog_id = os.getenv("DERIVA_PY_TEST_CATALOG")
53
+ if catalog_id is not None:
54
+ logger.info(f"Reusing catalog {catalog_id} on host {hostname}")
55
+ cls.catalog = server.connect_ermrest(catalog_id)
56
+ cls._purgeCatalog()
57
+ else:
58
+ cls.catalog = server.create_ermrest_catalog()
59
+ logger.info(f"Created catalog {cls.catalog.catalog_id} on host {hostname}")
60
+
61
+ @classmethod
62
+ def tearDownClass(cls):
63
+ if cls.catalog and os.getenv("DERIVA_PY_TEST_CATALOG") is None:
64
+ logger.info(f"Deleting catalog {cls.catalog.catalog_id} on host {hostname}")
65
+ cls.catalog.delete_ermrest_catalog(really=True)
66
+
67
+ def setUp(self):
68
+ self.model = self.catalog.getCatalogModel()
69
+
70
+ def tearDown(self):
71
+ self._purgeCatalog()
72
+
73
+ def _create_schema_with_fkeys(self):
74
+ """Creates a simple schema of two tables with a fkey relationship from child to parent."""
75
+
76
+ # build a single, low-level catalog /schema POST operation
77
+ # should be (slightly) faster and avoids using the client APIs under test in this module
78
+ schema_def = ermrest_model.Schema.define('schema_with_fkeys')
79
+ schema_def["tables"] = {
80
+ "parent": ermrest_model.Table.define(
81
+ 'parent',
82
+ column_defs=[
83
+ ermrest_model.Column.define('id', ermrest_model.builtin_types.text),
84
+ ermrest_model.Column.define('id_extra', ermrest_model.builtin_types.text),
85
+ ],
86
+ key_defs=[
87
+ ermrest_model.Key.define(['id'], constraint_name='parent_id_key'),
88
+ ermrest_model.Key.define(['id', 'id_extra'], constraint_name='parent_compound_key'),
89
+ ]
90
+ ),
91
+ "child": ermrest_model.Table.define(
92
+ 'child',
93
+ column_defs=[
94
+ ermrest_model.Column.define('parent_id', ermrest_model.builtin_types.text),
95
+ ermrest_model.Column.define('parent_id_extra', ermrest_model.builtin_types.text),
96
+ ],
97
+ fkey_defs=[
98
+ ermrest_model.ForeignKey.define(
99
+ ['parent_id'], 'schema_with_fkeys', 'parent', ['id']
100
+ ),
101
+ ermrest_model.ForeignKey.define(
102
+ ['parent_id_extra', 'parent_id'], 'schema_with_fkeys', 'parent', ['id_extra', 'id']
103
+ )
104
+ ]
105
+ ),
106
+ }
107
+ self.catalog.post('/schema', json=[schema_def])
108
+ # refresh the local state of the model
109
+ self.model = self.catalog.getCatalogModel()
110
+
111
+ def test_0a_schema_define_defaults(self):
112
+ sname = "test_schema"
113
+ sdef = ermrest_model.Schema.define(sname)
114
+ self.assertEqual(sdef.get("schema_name"), sname)
115
+ self.assertEqual(sdef.get("comment"), None)
116
+ self.assertEqual(sdef.get("acls"), dict())
117
+ self.assertEqual(sdef.get("annotations"), dict())
118
+
119
+ _test_comment = "my comment"
120
+ _test_acls = {
121
+ "insert": ["a"],
122
+ "update": ["b"],
123
+ }
124
+ _test_acl_bindings = {
125
+ }
126
+ _test_annotations = {"tag1": "value1"}
127
+
128
+ def test_0b_schema_define_custom(self):
129
+ sname = "test_schema"
130
+ sdef = ermrest_model.Schema.define(sname, self._test_comment, self._test_acls, self._test_annotations)
131
+ self.assertEqual(sdef.get("schema_name"), sname)
132
+ self.assertEqual(sdef.get("comment"), self._test_comment)
133
+ self.assertEqual(sdef.get("acls"), self._test_acls)
134
+ self.assertEqual(sdef.get("annotations"), self._test_annotations)
135
+
136
+ def test_1a_column_define_defaults(self):
137
+ cname = "test_column"
138
+ cdef = ermrest_model.Column.define(cname, ermrest_model.builtin_types.text)
139
+ self.assertEqual(cdef.get("name"), cname)
140
+ ctype = cdef.get("type")
141
+ self.assertIsInstance(ctype, dict)
142
+ self.assertEqual(ctype.get("typename"), "text")
143
+ self.assertEqual(cdef.get("nullok"), True)
144
+ self.assertEqual(cdef.get("default"), None)
145
+ self.assertEqual(cdef.get("comment"), None)
146
+ self.assertEqual(cdef.get("acls"), dict())
147
+ self.assertEqual(cdef.get("acl_bindings"), dict())
148
+ self.assertEqual(cdef.get("annotations"), dict())
149
+
150
+ def test_1b_column_define_custom(self):
151
+ cname = "test_column"
152
+ nullok = False
153
+ default = "my default"
154
+ cdef = ermrest_model.Column.define(
155
+ cname, ermrest_model.builtin_types.text, nullok, default,
156
+ self._test_comment, self._test_acls, self._test_acl_bindings, self._test_annotations,
157
+ )
158
+ self.assertEqual(cdef.get("name"), cname)
159
+ ctype = cdef.get("type")
160
+ self.assertIsInstance(ctype, dict)
161
+ self.assertEqual(ctype.get("typename"), "text")
162
+ self.assertEqual(cdef.get("nullok"), nullok)
163
+ self.assertEqual(cdef.get("default"), default)
164
+ self.assertEqual(cdef.get("comment"), self._test_comment)
165
+ self.assertEqual(cdef.get("acls"), self._test_acls)
166
+ self.assertEqual(cdef.get("acl_bindings"), self._test_acl_bindings)
167
+ self.assertEqual(cdef.get("annotations"), self._test_annotations)
168
+
169
+ def test_1c_key_define_defaults(self):
170
+ cnames = ["id"]
171
+ kdef = ermrest_model.Key.define(cnames)
172
+ self.assertEqual(kdef.get("unique_columns"), cnames)
173
+ self.assertEqual(not kdef.get("names"), True)
174
+ self.assertEqual(kdef.get("comment"), None)
175
+ self.assertEqual(kdef.get("annotations"), dict())
176
+
177
+ def test_1d_key_define_custom(self):
178
+ cnames = ["id"]
179
+ constraint_name = "my_constraint"
180
+ kdef = ermrest_model.Key.define(cnames, None, self._test_comment, self._test_annotations, constraint_name)
181
+ self.assertEqual(kdef.get("unique_columns"), cnames)
182
+ self.assertIsInstance(kdef.get("names"), list)
183
+ self.assertIsInstance(kdef.get("names")[0], list)
184
+ self.assertEqual(kdef.get("names")[0][1], constraint_name)
185
+ self.assertEqual(kdef.get("comment"), self._test_comment)
186
+ self.assertEqual(kdef.get("annotations"), self._test_annotations)
187
+
188
+ def test_1e_fkey_define_defaults(self):
189
+ fk_colnames = ["fk1"]
190
+ pk_sname = "pk_schema"
191
+ pk_tname = "pk_table"
192
+ pk_colnames = ["RID"]
193
+ fkdef = ermrest_model.ForeignKey.define(
194
+ fk_colnames,
195
+ pk_sname,
196
+ pk_tname,
197
+ pk_colnames,
198
+ )
199
+ self.assertEqual([ c.get("column_name") for c in fkdef.get("foreign_key_columns") ], fk_colnames)
200
+ self.assertEqual([ c.get("column_name") for c in fkdef.get("referenced_columns") ], pk_colnames)
201
+ self.assertEqual(all([ c.get("schema_name") == pk_sname for c in fkdef.get("referenced_columns") ]), True)
202
+ self.assertEqual(all([ c.get("table_name") == pk_tname for c in fkdef.get("referenced_columns") ]), True)
203
+ self.assertEqual(fkdef.get("on_update"), "NO ACTION")
204
+ self.assertEqual(fkdef.get("on_delete"), "NO ACTION")
205
+ self.assertEqual(not fkdef.get("names"), True)
206
+ self.assertEqual(fkdef.get("comment"), None)
207
+ self.assertEqual(fkdef.get("acls"), dict())
208
+ self.assertEqual(fkdef.get("acl_bindings"), dict())
209
+ self.assertEqual(fkdef.get("annotations"), dict())
210
+
211
+ def test_1f_fkey_define_custom(self):
212
+ fk_colnames = ["fk1"]
213
+ pk_sname = "pk_schema"
214
+ pk_tname = "pk_table"
215
+ pk_colnames = ["RID"]
216
+ constraint_name = "my_constraint"
217
+ action1 = "CASCADE"
218
+ action2 = "RESTRICT"
219
+ fkdef = ermrest_model.ForeignKey.define(
220
+ fk_colnames,
221
+ pk_sname,
222
+ pk_tname,
223
+ pk_colnames,
224
+ action1,
225
+ action2,
226
+ None,
227
+ self._test_comment,
228
+ self._test_acls,
229
+ self._test_acl_bindings,
230
+ self._test_annotations,
231
+ constraint_name,
232
+ )
233
+ self.assertEqual([ c.get("column_name") for c in fkdef.get("foreign_key_columns") ], fk_colnames)
234
+ self.assertEqual([ c.get("column_name") for c in fkdef.get("referenced_columns") ], pk_colnames)
235
+ self.assertEqual(all([ c.get("schema_name") == pk_sname for c in fkdef.get("referenced_columns") ]), True)
236
+ self.assertEqual(all([ c.get("table_name") == pk_tname for c in fkdef.get("referenced_columns") ]), True)
237
+ self.assertEqual(fkdef.get("on_update"), action1)
238
+ self.assertEqual(fkdef.get("on_delete"), action2)
239
+ self.assertIsInstance(fkdef.get("names"), list)
240
+ self.assertIsInstance(fkdef.get("names")[0], list)
241
+ self.assertEqual(fkdef.get("names")[0][1], constraint_name)
242
+ self.assertEqual(fkdef.get("comment"), self._test_comment)
243
+ self.assertEqual(fkdef.get("acls"), self._test_acls)
244
+ self.assertEqual(fkdef.get("acl_bindings"), self._test_acl_bindings)
245
+ self.assertEqual(fkdef.get("annotations"), self._test_annotations)
246
+
247
+ def test_2a_table_define_defaults(self):
248
+ tname = "test_table"
249
+ tdef = ermrest_model.Table.define(
250
+ tname,
251
+ [
252
+ ermrest_model.Column.define("id", ermrest_model.builtin_types.text),
253
+ ],
254
+ )
255
+ self.assertEqual(tdef.get("table_name"), tname)
256
+ cdefs = tdef.get("column_definitions")
257
+ self.assertIsInstance(cdefs, list)
258
+ self.assertEqual(len(cdefs), 5 + 1)
259
+ kdefs = tdef.get("keys")
260
+ self.assertIsInstance(kdefs, list)
261
+ self.assertEqual(len(kdefs), 1)
262
+ fkdefs = tdef.get("foreign_keys")
263
+ self.assertIsInstance(fkdefs, list)
264
+ self.assertEqual(len(fkdefs), 2)
265
+ self.assertEqual(tdef.get("comment"), None)
266
+ self.assertEqual(tdef.get("acls"), dict())
267
+ self.assertEqual(tdef.get("acl_bindings"), dict())
268
+ self.assertEqual(tdef.get("annotations"), dict())
269
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
270
+ table = schema.create_table(tdef)
271
+ self.assertIsInstance(table, ermrest_model.Table)
272
+
273
+ def test_2b_table_define_custom(self):
274
+ tname = "test_table"
275
+ tdef = ermrest_model.Table.define(
276
+ tname,
277
+ [
278
+ ermrest_model.Column.define("id", ermrest_model.builtin_types.text),
279
+ ermrest_model.Column.define("fk1", ermrest_model.builtin_types.text),
280
+ ],
281
+ [
282
+ ermrest_model.Key.define(["id"]),
283
+ ],
284
+ [
285
+ ermrest_model.ForeignKey.define(["fk1"], "public", "ERMrest_Client", ["RID"]),
286
+ ],
287
+ self._test_comment,
288
+ self._test_acls,
289
+ self._test_acl_bindings,
290
+ self._test_annotations,
291
+ provide_system_fkeys=False,
292
+ )
293
+ self.assertEqual(tdef.get("table_name"), tname)
294
+ cdefs = tdef.get("column_definitions")
295
+ self.assertIsInstance(cdefs, list)
296
+ self.assertEqual(len(cdefs), 5 + 2)
297
+ kdefs = tdef.get("keys")
298
+ self.assertIsInstance(kdefs, list)
299
+ self.assertEqual(len(kdefs), 1 + 1)
300
+ fkdefs = tdef.get("foreign_keys")
301
+ self.assertIsInstance(fkdefs, list)
302
+ self.assertEqual(len(fkdefs), 1)
303
+ self.assertEqual(tdef.get("comment"), self._test_comment)
304
+ self.assertEqual(tdef.get("acls"), self._test_acls)
305
+ self.assertEqual(tdef.get("acl_bindings"), self._test_acl_bindings)
306
+ self.assertEqual(tdef.get("annotations"), self._test_annotations)
307
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
308
+ table = schema.create_table(tdef)
309
+ self.assertIsInstance(table, ermrest_model.Table)
310
+
311
+ def test_2c_table_define_with_reference(self):
312
+ tname = "test_table"
313
+ tdef = ermrest_model.Table.define(
314
+ tname,
315
+ [
316
+ ermrest_model.Column.define("id", ermrest_model.builtin_types.text),
317
+ self.model.schemas["public"].tables["ERMrest_Client"],
318
+ ],
319
+ [],
320
+ [],
321
+ self._test_comment,
322
+ self._test_acls,
323
+ self._test_acl_bindings,
324
+ self._test_annotations,
325
+ )
326
+ self.assertEqual(tdef.get("table_name"), tname)
327
+ cdefs = tdef.get("column_definitions")
328
+ self.assertIsInstance(cdefs, list)
329
+ self.assertEqual(len(cdefs), 5 + 2)
330
+ kdefs = tdef.get("keys")
331
+ self.assertIsInstance(kdefs, list)
332
+ self.assertEqual(len(kdefs), 1)
333
+ fkdefs = tdef.get("foreign_keys")
334
+ self.assertIsInstance(fkdefs, list)
335
+ self.assertEqual(len(fkdefs), 2 + 1)
336
+ self.assertEqual(
337
+ {
338
+ (
339
+ fkdef["referenced_columns"][0]["schema_name"],
340
+ fkdef["referenced_columns"][0]["table_name"],
341
+ frozenset(zip(
342
+ ( c["column_name"] for c in fkdef["foreign_key_columns"] ),
343
+ ( c["column_name"] for c in fkdef["referenced_columns"] ),
344
+ ))
345
+ )
346
+ for fkdef in fkdefs
347
+ },
348
+ {
349
+ ("public", "ERMrest_Client", frozenset([ ("ERMrest_Client", "ID",) ])),
350
+ ("public", "ERMrest_Client", frozenset([ ("RCB", "ID",) ])),
351
+ ("public", "ERMrest_Client", frozenset([ ("RMB", "ID",) ])),
352
+ }
353
+ )
354
+ self.assertEqual(tdef.get("comment"), self._test_comment)
355
+ self.assertEqual(tdef.get("acls"), self._test_acls)
356
+ self.assertEqual(tdef.get("acl_bindings"), self._test_acl_bindings)
357
+ self.assertEqual(tdef.get("annotations"), self._test_annotations)
358
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
359
+ table = schema.create_table(tdef)
360
+ self.assertIsInstance(table, ermrest_model.Table)
361
+
362
+ def test_3a_vocab_define_defaults(self):
363
+ tname = "test_table"
364
+ curie_template = "test:{RID}"
365
+ tdef = ermrest_model.Table.define_vocabulary(
366
+ tname,
367
+ curie_template,
368
+ )
369
+ self.assertEqual(tdef.get("table_name"), tname)
370
+ cdefs = tdef.get("column_definitions")
371
+ self.assertIsInstance(cdefs, list)
372
+ self.assertEqual(len(cdefs), 5 + 5)
373
+ self.assertEqual({ c["name"] for c in cdefs }, {"RID","RCT","RMT","RCB","RMB","ID","Name","Description","Synonyms","URI"})
374
+ cdefs = { c["name"]: c for c in cdefs }
375
+ self.assertEqual(cdefs["ID"]["default"], curie_template)
376
+ self.assertEqual(cdefs["URI"]["default"], '/id/{RID}')
377
+ kdefs = tdef.get("keys")
378
+ self.assertIsInstance(kdefs, list)
379
+ self.assertEqual(len(kdefs), 1 + 3)
380
+ fkdefs = tdef.get("foreign_keys")
381
+ self.assertIsInstance(fkdefs, list)
382
+ self.assertEqual(len(fkdefs), 2)
383
+ self.assertEqual(tdef.get("comment"), None)
384
+ self.assertEqual(tdef.get("acls"), dict())
385
+ self.assertEqual(tdef.get("acl_bindings"), dict())
386
+ self.assertEqual(tdef.get("annotations"), dict())
387
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
388
+ table = schema.create_table(tdef)
389
+ self.assertIsInstance(table, ermrest_model.Table)
390
+
391
+ def test_3b_vocab_define_custom(self):
392
+ tname = "test_table"
393
+ curie_template = "test:{RID}"
394
+ uri_template = "/id/1/{RID}"
395
+ tdef = ermrest_model.Table.define_vocabulary(
396
+ tname,
397
+ curie_template,
398
+ uri_template,
399
+ [
400
+ ermrest_model.Column.define("fk1", ermrest_model.builtin_types.text),
401
+ ],
402
+ [],
403
+ [
404
+ ermrest_model.ForeignKey.define(["fk1"], "public", "ERMrest_Client", ["RID"]),
405
+ ],
406
+ self._test_comment,
407
+ self._test_acls,
408
+ self._test_acl_bindings,
409
+ self._test_annotations,
410
+ provide_name_key=False,
411
+ provide_system_fkeys=False,
412
+ )
413
+ self.assertEqual(tdef.get("table_name"), tname)
414
+ cdefs = tdef.get("column_definitions")
415
+ self.assertIsInstance(cdefs, list)
416
+ self.assertEqual(len(cdefs), 5 + 5 + 1)
417
+ self.assertEqual({ c["name"] for c in cdefs }, {"RID","RCT","RMT","RCB","RMB","ID","Name","Description","Synonyms","URI","fk1"})
418
+ cdefs = { c["name"]: c for c in cdefs }
419
+ self.assertEqual(cdefs["ID"]["default"], curie_template)
420
+ self.assertEqual(cdefs["URI"]["default"], uri_template)
421
+ kdefs = tdef.get("keys")
422
+ self.assertIsInstance(kdefs, list)
423
+ self.assertEqual(len(kdefs), 1 + 2)
424
+ fkdefs = tdef.get("foreign_keys")
425
+ self.assertIsInstance(fkdefs, list)
426
+ self.assertEqual(len(fkdefs), 1)
427
+ self.assertEqual(tdef.get("comment"), self._test_comment)
428
+ self.assertEqual(tdef.get("acls"), self._test_acls)
429
+ self.assertEqual(tdef.get("acl_bindings"), self._test_acl_bindings)
430
+ self.assertEqual(tdef.get("annotations"), self._test_annotations)
431
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
432
+ table = schema.create_table(tdef)
433
+ self.assertIsInstance(table, ermrest_model.Table)
434
+
435
+ def test_3c_vocab_define_with_reference(self):
436
+ tname = "test_table"
437
+ curie_template = "test:{RID}"
438
+ uri_template = "/id/1/{RID}"
439
+ target = self.model.schemas["public"].tables["ERMrest_Client"]
440
+ self.assertIsInstance(target, ermrest_model.Table)
441
+ tdef = ermrest_model.Table.define_vocabulary(
442
+ tname,
443
+ curie_template,
444
+ uri_template,
445
+ [ target, ],
446
+ [],
447
+ [],
448
+ self._test_comment,
449
+ self._test_acls,
450
+ self._test_acl_bindings,
451
+ self._test_annotations,
452
+ )
453
+ self.assertEqual(tdef.get("table_name"), tname)
454
+ cdefs = tdef.get("column_definitions")
455
+ self.assertIsInstance(cdefs, list)
456
+ self.assertEqual(len(cdefs), 5 + 5 + 1)
457
+ self.assertEqual({ c["name"] for c in cdefs }, {"RID","RCT","RMT","RCB","RMB","ID","Name","Description","Synonyms","URI","ERMrest_Client"})
458
+ kdefs = tdef.get("keys")
459
+ self.assertIsInstance(kdefs, list)
460
+ self.assertEqual(len(kdefs), 1 + 3)
461
+ fkdefs = tdef.get("foreign_keys")
462
+ self.assertIsInstance(fkdefs, list)
463
+ self.assertEqual(len(fkdefs), 2 + 1)
464
+ self.assertEqual(
465
+ {
466
+ (
467
+ fkdef["referenced_columns"][0]["schema_name"],
468
+ fkdef["referenced_columns"][0]["table_name"],
469
+ frozenset(zip(
470
+ ( c["column_name"] for c in fkdef["foreign_key_columns"] ),
471
+ ( c["column_name"] for c in fkdef["referenced_columns"] ),
472
+ ))
473
+ )
474
+ for fkdef in fkdefs
475
+ },
476
+ {
477
+ ("public", "ERMrest_Client", frozenset([ ("ERMrest_Client", "ID",) ])),
478
+ ("public", "ERMrest_Client", frozenset([ ("RCB", "ID",) ])),
479
+ ("public", "ERMrest_Client", frozenset([ ("RMB", "ID",) ])),
480
+ }
481
+ )
482
+ self.assertEqual(tdef.get("comment"), self._test_comment)
483
+ self.assertEqual(tdef.get("acls"), self._test_acls)
484
+ self.assertEqual(tdef.get("acl_bindings"), self._test_acl_bindings)
485
+ self.assertEqual(tdef.get("annotations"), self._test_annotations)
486
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
487
+ table = schema.create_table(tdef)
488
+ self.assertIsInstance(table, ermrest_model.Table)
489
+
490
+ def test_4a_asset_define_defaults(self):
491
+ tname = "test_table"
492
+ tdef = ermrest_model.Table.define_asset(
493
+ "model_define_schema",
494
+ tname,
495
+ )
496
+ self.assertEqual(tdef.get("table_name"), tname)
497
+ cdefs = tdef.get("column_definitions")
498
+ self.assertIsInstance(cdefs, list)
499
+ self.assertEqual(len(cdefs), 5 + 5)
500
+ self.assertEqual({ c["name"] for c in cdefs }, {"RID","RCT","RMT","RCB","RMB","Filename","Description","Length","MD5","URL"})
501
+ cdefs = { c["name"]: c for c in cdefs }
502
+ kdefs = tdef.get("keys")
503
+ self.assertIsInstance(kdefs, list)
504
+ self.assertEqual(len(kdefs), 1 + 1)
505
+ fkdefs = tdef.get("foreign_keys")
506
+ self.assertIsInstance(fkdefs, list)
507
+ self.assertEqual(len(fkdefs), 2)
508
+ self.assertEqual(tdef.get("acls"), dict())
509
+ self.assertEqual(tdef.get("acl_bindings"), dict())
510
+ self.assertEqual(set(tdef.get("annotations").keys()), {tag.table_display})
511
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
512
+ table = schema.create_table(tdef)
513
+ self.assertIsInstance(table, ermrest_model.Table)
514
+
515
+ def test_4b_asset_define_custom(self):
516
+ tname = "test_table"
517
+ hatrac_template = "/hatrac/foo/{{{MD5}}}.{{{Filename}}}"
518
+ tdef = ermrest_model.Table.define_asset(
519
+ "model_define_schema",
520
+ tname,
521
+ hatrac_template,
522
+ [
523
+ ermrest_model.Column.define("fk1", ermrest_model.builtin_types.text),
524
+ ],
525
+ [],
526
+ [
527
+ ermrest_model.ForeignKey.define(["fk1"], "public", "ERMrest_Client", ["RID"]),
528
+ ],
529
+ self._test_comment,
530
+ self._test_acls,
531
+ self._test_acl_bindings,
532
+ self._test_annotations,
533
+ provide_system_fkeys=False,
534
+ )
535
+ self.assertEqual(tdef.get("table_name"), tname)
536
+ cdefs = tdef.get("column_definitions")
537
+ self.assertIsInstance(cdefs, list)
538
+ self.assertEqual(len(cdefs), 5 + 5 + 1)
539
+ self.assertEqual({ c["name"] for c in cdefs }, {"RID","RCT","RMT","RCB","RMB","Filename","Description","Length","MD5","URL","fk1"})
540
+ cdefs = { c["name"]: c for c in cdefs }
541
+ self.assertEqual(cdefs["URL"]["annotations"][tag.asset]["url_pattern"], hatrac_template)
542
+ kdefs = tdef.get("keys")
543
+ self.assertIsInstance(kdefs, list)
544
+ self.assertEqual(len(kdefs), 1 + 1)
545
+ fkdefs = tdef.get("foreign_keys")
546
+ self.assertIsInstance(fkdefs, list)
547
+ self.assertEqual(len(fkdefs), 1)
548
+ self.assertEqual(tdef.get("comment"), self._test_comment)
549
+ self.assertEqual(tdef.get("acls"), self._test_acls)
550
+ self.assertEqual(tdef.get("acl_bindings"), self._test_acl_bindings)
551
+ annotations = tdef.get("annotations")
552
+ for k, v in self._test_annotations.items():
553
+ self.assertEqual(annotations[k], v)
554
+ self.assertIn(tag.table_display, annotations)
555
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
556
+ table = schema.create_table(tdef)
557
+ self.assertIsInstance(table, ermrest_model.Table)
558
+
559
+ def test_4c_asset_define_with_reference(self):
560
+ tname = "test_table"
561
+ hatrac_template = "/hatrac/foo/{{{MD5}}}.{{{Filename}}}"
562
+ target = self.model.schemas["public"].tables["ERMrest_Client"]
563
+ self.assertIsInstance(target, ermrest_model.Table)
564
+ tdef = ermrest_model.Table.define_asset(
565
+ "model_define_schema",
566
+ tname,
567
+ hatrac_template,
568
+ [ target, ],
569
+ [],
570
+ [],
571
+ self._test_comment,
572
+ self._test_acls,
573
+ self._test_acl_bindings,
574
+ self._test_annotations,
575
+ )
576
+ self.assertEqual(tdef.get("table_name"), tname)
577
+ cdefs = tdef.get("column_definitions")
578
+ self.assertIsInstance(cdefs, list)
579
+ self.assertEqual(len(cdefs), 5 + 5 + 1)
580
+ self.assertEqual({ c["name"] for c in cdefs }, {"RID","RCT","RMT","RCB","RMB","Filename","Description","Length","MD5","URL","ERMrest_Client"})
581
+ kdefs = tdef.get("keys")
582
+ self.assertIsInstance(kdefs, list)
583
+ self.assertEqual(len(kdefs), 1 + 1)
584
+ fkdefs = tdef.get("foreign_keys")
585
+ self.assertIsInstance(fkdefs, list)
586
+ self.assertEqual(len(fkdefs), 2 + 1)
587
+ self.assertEqual(
588
+ {
589
+ (
590
+ fkdef["referenced_columns"][0]["schema_name"],
591
+ fkdef["referenced_columns"][0]["table_name"],
592
+ frozenset(zip(
593
+ ( c["column_name"] for c in fkdef["foreign_key_columns"] ),
594
+ ( c["column_name"] for c in fkdef["referenced_columns"] ),
595
+ ))
596
+ )
597
+ for fkdef in fkdefs
598
+ },
599
+ {
600
+ ("public", "ERMrest_Client", frozenset([ ("ERMrest_Client", "ID",) ])),
601
+ ("public", "ERMrest_Client", frozenset([ ("RCB", "ID",) ])),
602
+ ("public", "ERMrest_Client", frozenset([ ("RMB", "ID",) ])),
603
+ }
604
+ )
605
+ self.assertEqual(tdef.get("comment"), self._test_comment)
606
+ self.assertEqual(tdef.get("acls"), self._test_acls)
607
+ self.assertEqual(tdef.get("acl_bindings"), self._test_acl_bindings)
608
+ annotations = tdef.get("annotations")
609
+ for k, v in self._test_annotations.items():
610
+ self.assertEqual(annotations[k], v)
611
+ self.assertIn(tag.table_display, annotations)
612
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
613
+ table = schema.create_table(tdef)
614
+ self.assertIsInstance(table, ermrest_model.Table)
615
+
616
+ def test_5a_assoctable_define_defaults(self):
617
+ tdef = ermrest_model.Table.define_association(
618
+ [
619
+ self.model.schemas["public"].tables["ERMrest_Client"],
620
+ self.model.schemas["public"].tables["ERMrest_Group"],
621
+ ],
622
+ )
623
+ self.assertEqual(tdef.get("table_name"), "ERMrest_Client_ERMrest_Group")
624
+ self.assertEqual(tdef.get("comment"), None)
625
+ cdefs = tdef.get("column_definitions")
626
+ self.assertIsInstance(cdefs, list)
627
+ self.assertEqual(len(cdefs), 5 + 2)
628
+ kdefs = tdef.get("keys")
629
+ self.assertIsInstance(kdefs, list)
630
+ self.assertEqual(
631
+ { tuple(key["unique_columns"]) for key in kdefs },
632
+ { ('RID',), ('ERMrest_Client', 'ERMrest_Group') },
633
+ )
634
+ fkdefs = tdef.get("foreign_keys")
635
+ self.assertIsInstance(fkdefs, list)
636
+ self.assertEqual(
637
+ {
638
+ (
639
+ fkdef["referenced_columns"][0]["schema_name"],
640
+ fkdef["referenced_columns"][0]["table_name"],
641
+ frozenset(zip(
642
+ tuple( c["column_name"] for c in fkdef["foreign_key_columns"] ),
643
+ tuple( c["column_name"] for c in fkdef["referenced_columns"] ),
644
+ ))
645
+ )
646
+ for fkdef in fkdefs
647
+ },
648
+ {
649
+ ("public", "ERMrest_Client", frozenset([ ("ERMrest_Client", "ID",) ])),
650
+ ("public", "ERMrest_Group", frozenset([ ("ERMrest_Group", "ID",) ])),
651
+ ("public", "ERMrest_Client", frozenset([ ("RCB", "ID",) ])),
652
+ ("public", "ERMrest_Client", frozenset([ ("RMB", "ID",) ])),
653
+ }
654
+ )
655
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
656
+ table = schema.create_table(tdef)
657
+ self.assertIsInstance(table, ermrest_model.Table)
658
+
659
+ def test_5b_assoctable_define_custom(self):
660
+ tname = "client_group"
661
+ tdef = ermrest_model.Table.define_association(
662
+ [
663
+ ('c_id', self.model.schemas["public"].tables["ERMrest_Client"]),
664
+ ('g_id', self.model.schemas["public"].tables["ERMrest_Group"]),
665
+ ],
666
+ [],
667
+ tname,
668
+ self._test_comment,
669
+ provide_system_fkeys=False,
670
+ )
671
+ self.assertEqual(tdef.get("table_name"), tname)
672
+ self.assertEqual(tdef.get("comment"), self._test_comment)
673
+ cdefs = tdef.get("column_definitions")
674
+ self.assertIsInstance(cdefs, list)
675
+ self.assertEqual(len(cdefs), 5 + 2)
676
+ kdefs = tdef.get("keys")
677
+ self.assertIsInstance(kdefs, list)
678
+ self.assertEqual(
679
+ { tuple(key["unique_columns"]) for key in kdefs },
680
+ { ('RID',), ('c_id', 'g_id') },
681
+ )
682
+ fkdefs = tdef.get("foreign_keys")
683
+ self.assertIsInstance(fkdefs, list)
684
+ self.assertEqual(
685
+ {
686
+ (
687
+ fkdef["referenced_columns"][0]["schema_name"],
688
+ fkdef["referenced_columns"][0]["table_name"],
689
+ frozenset(zip(
690
+ tuple( c["column_name"] for c in fkdef["foreign_key_columns"] ),
691
+ tuple( c["column_name"] for c in fkdef["referenced_columns"] ),
692
+ ))
693
+ )
694
+ for fkdef in fkdefs
695
+ },
696
+ {
697
+ ("public", "ERMrest_Client", frozenset([ ("c_id", "ID",) ])),
698
+ ("public", "ERMrest_Group", frozenset([ ("g_id", "ID",) ])),
699
+ }
700
+ )
701
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
702
+ table = schema.create_table(tdef)
703
+ self.assertIsInstance(table, ermrest_model.Table)
704
+
705
+ def test_5c_assoctable_define_with_metadata(self):
706
+ tname = "client_group"
707
+ tdef = ermrest_model.Table.define_association(
708
+ [
709
+ ('c_id', self.model.schemas["public"].tables["ERMrest_Client"]),
710
+ ('g_id', self.model.schemas["public"].tables["ERMrest_Group"]),
711
+ ],
712
+ [
713
+ ermrest_model.Column.define("md1", ermrest_model.builtin_types.text),
714
+ ],
715
+ tname,
716
+ self._test_comment,
717
+ )
718
+ self.assertEqual(tdef.get("table_name"), tname)
719
+ self.assertEqual(tdef.get("comment"), self._test_comment)
720
+ cdefs = tdef.get("column_definitions")
721
+ self.assertIsInstance(cdefs, list)
722
+ self.assertEqual(len(cdefs), 5 + 2 + 1)
723
+ kdefs = tdef.get("keys")
724
+ self.assertIsInstance(kdefs, list)
725
+ self.assertEqual(
726
+ { tuple(key["unique_columns"]) for key in kdefs },
727
+ { ('RID',), ('c_id', 'g_id') },
728
+ )
729
+ fkdefs = tdef.get("foreign_keys")
730
+ self.assertIsInstance(fkdefs, list)
731
+ self.assertEqual(
732
+ {
733
+ (
734
+ fkdef["referenced_columns"][0]["schema_name"],
735
+ fkdef["referenced_columns"][0]["table_name"],
736
+ frozenset(zip(
737
+ tuple( c["column_name"] for c in fkdef["foreign_key_columns"] ),
738
+ tuple( c["column_name"] for c in fkdef["referenced_columns"] ),
739
+ ))
740
+ )
741
+ for fkdef in fkdefs
742
+ },
743
+ {
744
+ ("public", "ERMrest_Client", frozenset([ ("c_id", "ID",) ])),
745
+ ("public", "ERMrest_Group", frozenset([ ("g_id", "ID",) ])),
746
+ ("public", "ERMrest_Client", frozenset([ ("RCB", "ID",) ])),
747
+ ("public", "ERMrest_Client", frozenset([ ("RMB", "ID",) ])),
748
+ }
749
+ )
750
+ schema = self.model.create_schema(ermrest_model.Schema.define("model_define_schema"))
751
+ table = schema.create_table(tdef)
752
+ self.assertIsInstance(table, ermrest_model.Table)
753
+
754
+ def test_key_drop_cascading(self):
755
+ self._create_schema_with_fkeys()
756
+ schema = self.model.schemas['schema_with_fkeys']
757
+ self.model.schemas['schema_with_fkeys'].tables['parent'].keys[(schema, 'parent_id_key')].drop(cascade=True)
758
+
759
+ def test_key_reordered_drop_cascading(self):
760
+ self._create_schema_with_fkeys()
761
+ schema = self.model.schemas['schema_with_fkeys']
762
+ self.model.schemas['schema_with_fkeys'].tables['parent'].keys[(schema, 'parent_compound_key')].drop(cascade=True)
763
+
764
+ def test_key_column_drop_cascading(self):
765
+ self._create_schema_with_fkeys()
766
+ self.model.schemas['schema_with_fkeys'].tables['parent'].columns['id'].drop(cascade=True)
767
+
768
+ def test_fkey_column_drop_cascading(self):
769
+ self._create_schema_with_fkeys()
770
+ self.model.schemas['schema_with_fkeys'].tables['child'].columns['parent_id_extra'].drop(cascade=True)
771
+
772
+ def test_table_drop_cascading(self):
773
+ self._create_schema_with_fkeys()
774
+ self.model.schemas['schema_with_fkeys'].tables['parent'].drop(cascade=True)
775
+
776
+ def test_schema_drop_cascading(self):
777
+ self._create_schema_with_fkeys()
778
+ self.model.schemas['schema_with_fkeys'].drop(cascade=True)
779
+
780
+
781
+ if __name__ == '__main__':
782
+ unittest.main()