Skip to content

Commit

Permalink
Merge pull request #517 from dimitri-yatsenko/master
Browse files Browse the repository at this point in the history
Fix issues #483, #516, and #518
  • Loading branch information
eywalker committed Nov 17, 2018
2 parents 9fdecfe + bae0900 commit 1b2827a
Show file tree
Hide file tree
Showing 27 changed files with 330 additions and 366 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Release notes

### 0.11.1 -- Nov 15, 2018
* Fix ordering of attributes in proj (#483 and #516)
* Prohibit direct insert into auto-populated tables (#511)

### 0.11.0 -- Oct 25, 2018
* Full support of dependencies with renamed attributes using projection syntax (#300, #345, #436, #506, #507)
* Rename internal class and module names to comply with terminology in documentation (#494, #500)
Expand Down
12 changes: 6 additions & 6 deletions datajoint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@
"""

import os
from types import ModuleType
from .version import __version__

__author__ = "Dimitri Yatsenko, Edgar Y. Walker, and Fabian Sinz at Baylor College of Medicine"
__date__ = "Oct 25, 2018"
__date__ = "Nov 15, 2018"
__all__ = ['__author__', '__version__',
'config', 'conn', 'kill', 'Table',
'Connection', 'Heading', 'FreeTable', 'Not', 'schema',
Expand Down Expand Up @@ -68,15 +67,15 @@ class key:
from .connection import conn, Connection
from .table import FreeTable, Table
from .user_tables import Manual, Lookup, Imported, Computed, Part
from .query import Not, AndList, U
from .expression import Not, AndList, U
from .heading import Heading
from .schema import Schema as schema
from .erd import ERD
from .admin import set_password, kill
from .errors import DataJointError, DuplicateError


def create_virtual_module(module_name, schema_name, create_schema=False, create_tables=False):
def create_virtual_module(module_name, schema_name, create_schema=False, create_tables=False, connection=None):
"""
Creates a python module with the given name from the name of a schema on the server and
automatically adds classes to it corresponding to the tables in the schema.
Expand All @@ -87,8 +86,9 @@ def create_virtual_module(module_name, schema_name, create_schema=False, create_
:param create_tables: if True, module.schema can be used as the decorator for declaring new
:return: the python module containing classes from the schema object and the table classes
"""
module = ModuleType(module_name)
_schema = schema(schema_name, create_schema=create_schema, create_tables=create_tables)
import types
module = types.ModuleType(module_name)
_schema = schema(schema_name, create_schema=create_schema, create_tables=create_tables, connection=connection)
_schema.spawn_missing_classes(context=module.__dict__)
module.__dict__['schema'] = _schema
return module
3 changes: 2 additions & 1 deletion datajoint/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ def kill(restriction=None, connection=None): # pragma: no cover
while True:
print(' ID USER STATE TIME INFO')
print('+--+ +----------+ +-----------+ +--+')
for process in connection.query(query, as_dict=True).fetchall():
cur = connection.query(query, as_dict=True)
for process in cur:
try:
print('{ID:>4d} {USER:<12s} {STATE:<12s} {TIME:>5d} {INFO}'.format(**process))
except TypeError:
Expand Down
4 changes: 2 additions & 2 deletions datajoint/autopopulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import random
from tqdm import tqdm
from pymysql import OperationalError
from .query import Query, AndList, U
from .expression import QueryExpression, AndList, U
from .errors import DataJointError
from .table import FreeTable
import signal
Expand Down Expand Up @@ -84,7 +84,7 @@ def _jobs_to_do(self, restrictions):
raise DataJointError('Cannot call populate on a restricted table. '
'Instead, pass conditions to populate() as arguments.')
todo = self.key_source
if not isinstance(todo, Query):
if not isinstance(todo, QueryExpression):
raise DataJointError('Invalid key_source value')
# check if target lacks any attributes from the primary key of key_source
try:
Expand Down
4 changes: 2 additions & 2 deletions datajoint/declare.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def compile_foreign_key(line, context, attributes, primary_key, attr_sql, foreig
"""
# Parse and validate
from .table import Table
from .query import Projection
from .expression import Projection

new_style = True # See issue #436. Old style to be deprecated in a future release
try:
Expand Down Expand Up @@ -194,7 +194,7 @@ def declare(full_table_name, definition, context):
:param full_table_name: full name of the table
:param definition: DataJoint table definition
:param context: dictionary of objects that might be referred to in the table. Usually this will be locals()
:param context: dictionary of objects that might be referred to in the table.
"""
# split definition into lines
definition = re.split(r'\s*\n\s*', definition.strip())
Expand Down
25 changes: 0 additions & 25 deletions datajoint/erd.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,31 +197,6 @@ def __mul__(self, arg):
self.nodes_to_show.intersection_update(arg.nodes_to_show)
return self

def topological_sort(self):
"""
:return: list of nodes in topological order
"""

def _unite(lst):
"""
reorder list so that parts immediately follow their masters without breaking the topological order.
Without this correction, simple topological sort may insert other descendants between master and parts
:example:
_unite(['a', 'a__q', 'b', 'c', 'c__q', 'b__q', 'd', 'a__r'])
-> ['a', 'a__q', 'a__r', 'b', 'b__q', 'c', 'c__q', 'd']
"""
if len(lst) <= 2:
return lst
el = lst.pop()
lst = _unite(lst)
if '__' in el:
master = el.split('__')[0]
if not lst[-1].startswith(master):
return _unite(lst[:-1] + [el, lst[-1]])
return lst + [el]

return _unite(list(nx.algorithms.dag.topological_sort(self.subgraph(self.nodes_to_show))))

def _make_graph(self):
"""
Make the self.graph - a graph object ready for drawing
Expand Down

0 comments on commit 1b2827a

Please sign in to comment.