Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions datajoint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
__all__ = ['__author__', '__version__',
'config', 'conn', 'kill',
'Connection', 'Heading', 'BaseRelation', 'FreeRelation', 'Not', 'schema',
'Manual', 'Lookup', 'Imported', 'Computed', 'Part']
'Manual', 'Lookup', 'Imported', 'Computed', 'Part',
'AndList', 'OrList']


class key:
Expand Down Expand Up @@ -57,7 +58,7 @@ class DataJointError(Exception):
* modify the local copy of %s that datajoint just saved for you
* put a file named %s with the same configuration format in your home
* specify the environment variables DJ_USER, DJ_HOST, DJ_PASS
""")
""" % (LOCALCONFIG, GLOBALCONFIG))
local_config_file = os.path.expanduser(LOCALCONFIG)
logger.log(logging.INFO, "No config found. Generating {0:s}".format(local_config_file))
config.save(local_config_file)
Expand All @@ -69,7 +70,7 @@ class DataJointError(Exception):
from .connection import conn, Connection
from .base_relation import BaseRelation
from .user_relations import Manual, Lookup, Imported, Computed, Part
from .relational_operand import Not
from .relational_operand import Not, AndList, OrList
from .heading import Heading
from .schema import Schema as schema
from .kill import kill
23 changes: 11 additions & 12 deletions datajoint/autopopulate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
import datetime
import random
from .relational_operand import RelationalOperand
from .relational_operand import RelationalOperand, AndList
from . import DataJointError
from .base_relation import FreeRelation

Expand Down Expand Up @@ -56,13 +56,12 @@ def target(self):
"""
return self

def populate(self, restriction=None, suppress_errors=False,
reserve_jobs=False, order="original"):
def populate(self, *restrictions, suppress_errors=False, reserve_jobs=False, order="original"):
"""
rel.populate() calls rel._make_tuples(key) for every primary key in self.populated_from
for which there is not already a tuple in rel.

:param restriction: restriction on rel.populated_from - target
:param restrictions: a list of restrictions each restrict (rel.populated_from - target.proj())
:param suppress_errors: suppresses error if true
:param reserve_jobs: if true, reserves job to populate in asynchronous fashion
:param order: "original"|"reverse"|"random" - the order of execution
Expand All @@ -77,13 +76,13 @@ def populate(self, restriction=None, suppress_errors=False,
todo = self.populated_from
if not isinstance(todo, RelationalOperand):
raise DataJointError('Invalid populated_from value')
todo.restrict(restriction)
todo.restrict(AndList(restrictions))

error_list = [] if suppress_errors else None

jobs = self.connection.jobs[self.target.database]
table_name = self.target.table_name
keys = (todo - self.target.project()).fetch.keys()
jobs = self.connection.jobs[self.target.database] if reserve_jobs else None
todo -= self.target.proj()
keys = todo.fetch.keys()
if order == "reverse":
keys = list(keys)
keys.reverse()
Expand All @@ -94,20 +93,20 @@ def populate(self, restriction=None, suppress_errors=False,
raise DataJointError('Invalid order specification')

for key in keys:
if not reserve_jobs or jobs.reserve(table_name, key):
if not reserve_jobs or jobs.reserve(self.target.table_name, key):
self.connection.start_transaction()
if key in self.target: # already populated
self.connection.cancel_transaction()
if reserve_jobs:
jobs.complete(table_name, key)
jobs.complete(self.target.table_name, key)
else:
logger.info('Populating: ' + str(key))
try:
self._make_tuples(dict(key))
except Exception as error:
self.connection.cancel_transaction()
if reserve_jobs:
jobs.error(table_name, key, error_message=str(error))
jobs.error(self.target.table_name, key, error_message=str(error))
if not suppress_errors:
raise
else:
Expand All @@ -116,7 +115,7 @@ def populate(self, restriction=None, suppress_errors=False,
else:
self.connection.commit_transaction()
if reserve_jobs:
jobs.complete(table_name, key)
jobs.complete(self.target.table_name, key)
return error_list

def progress(self, restriction=None, display=True):
Expand Down
2 changes: 1 addition & 1 deletion datajoint/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def keys(self, **kwargs):
"""
Iterator that returns primary keys.
"""
yield from self._relation.project().fetch.set_behavior(**dict(self.behavior, as_dict=True, **kwargs))
yield from self._relation.proj().fetch.set_behavior(**dict(self.behavior, as_dict=True, **kwargs))

def __getitem__(self, item):
"""
Expand Down
2 changes: 1 addition & 1 deletion datajoint/heading.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def init_from_database(self, conn, database, table_name):
attr['dtype'] = numeric_types[(t, is_unsigned)]
self.attributes = OrderedDict([(q['name'], Attribute(**q)) for q in attributes])

def project(self, *attribute_list, **renamed_attributes):
def proj(self, *attribute_list, **renamed_attributes):
"""
derive a new heading by selecting, renaming, or computing attributes.
In relational algebra these operators are known as project, rename, and expand.
Expand Down
Loading