Skip to content
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

Orm design refactor #2190

Merged
merged 4 commits into from
Nov 12, 2018
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
15 changes: 9 additions & 6 deletions .ci/test_plugin_testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,25 +57,28 @@ def get_computer(cls, temp_dir):
"""
Create and store a new computer, and return it
"""
computer = cls.backend.computers.create(
from aiida import orm

computer = orm.Computer(
name='localhost',
hostname='localhost',
description='my computer',
transport_type='local',
scheduler_type='direct',
workdir=temp_dir,
enabled_state=True)
computer.store()
enabled_state=True,
backend=cls.backend).store()
return computer

def test_data_loaded(self):
"""
Check that the data is indeed in the DB when calling load_node
"""
from aiida.orm.utils import load_node
from aiida import orm

self.assertTrue(is_dbenv_loaded())
self.assertEqual(load_node(self.data_pk).uuid, self.data.uuid)
self.assertEqual(self.backend.computers.get(name='localhost').uuid, self.computer.uuid)
self.assertEqual(orm.load_node(self.data_pk).uuid, self.data.uuid)
self.assertEqual(orm.Computer.objects(self.backend).get(name='localhost').uuid, self.computer.uuid)

def test_tear_down(self):
"""
Expand Down
10 changes: 3 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,11 @@
aiida/backends/djsite/__init__.py|
aiida/backends/djsite/manage.py|
aiida/backends/djsite/queries.py|
aiida/backends/djsite/querybuilder_django/dummy_model.py|
aiida/backends/djsite/querybuilder_django/querybuilder_django.py|
aiida/backends/djsite/settings/__init__.py|
aiida/backends/djsite/settings/settings_profile.py|
aiida/backends/djsite/settings/settings.py|
aiida/backends/djsite/settings/wsgi.py|
aiida/backends/general/abstractqueries.py|
aiida/backends/general/querybuilder_interface.py|
aiida/backends/__init__.py|
aiida/backends/profile.py|
aiida/backends/settings.py|
Expand Down Expand Up @@ -83,7 +80,6 @@
aiida/backends/sqlalchemy/models/utils.py|
aiida/backends/sqlalchemy/models/workflow.py|
aiida/backends/sqlalchemy/queries.py|
aiida/backends/sqlalchemy/querybuilder_sqla.py|
aiida/backends/sqlalchemy/tests/generic.py|
aiida/backends/sqlalchemy/tests/__init__.py|
aiida/backends/sqlalchemy/tests/migrations.py|
Expand Down Expand Up @@ -207,6 +203,7 @@
aiida/orm/authinfo.py|
aiida/orm/autogroup.py|
aiida/orm/backend.py|
aiida/orm/querybuilder.py|
aiida/orm/calculation/function.py|
aiida/orm/calculation/__init__.py|
aiida/orm/calculation/inline.py|
Expand Down Expand Up @@ -284,11 +281,11 @@
aiida/orm/implementation/sqlalchemy/user.py|
aiida/orm/implementation/sqlalchemy/utils.py|
aiida/orm/implementation/sqlalchemy/workflow.py|
aiida/orm/importexport.py|
aiida/orm/__init__.py|
aiida/orm/importexport.py|
aiida/orm/log.py|
aiida/orm/mixins.py|
aiida/orm/node.py|
aiida/orm/querybuilder.py|
aiida/orm/utils/__init__.py|
aiida/orm/utils/loaders.py|
aiida/orm/utils/remote.py|
Expand Down Expand Up @@ -356,7 +353,6 @@
aiida/utils/cli/options.py|
aiida/utils/cli/validators.py|
aiida/utils/delete_nodes.py|
aiida/utils/email.py|
aiida/utils/error_accumulator.py|
aiida/utils/find_folder.py|
aiida/utils/__init__.py|
Expand Down
19 changes: 8 additions & 11 deletions aiida/backends/djsite/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class DbUser(AbstractBaseUser, PermissionsMixin):

def get_aiida_class(self):
from aiida.orm.implementation.django.user import DjangoUser
from aiida.orm.backend import construct_backend
from aiida.orm.backends import construct_backend
return DjangoUser.from_dbmodel(self, construct_backend())


Expand Down Expand Up @@ -1399,7 +1399,7 @@ def get_dbcomputer(cls, computer):

def get_aiida_class(self):
from aiida.orm.implementation.django.computer import DjangoComputer
from aiida.orm.backend import construct_backend
from aiida.orm.backends import construct_backend
return DjangoComputer.from_dbmodel(self, construct_backend())

def _get_val_from_metadata(self, key):
Expand All @@ -1415,15 +1415,6 @@ def _get_val_from_metadata(self, key):
except KeyError:
raise ConfigurationError('No {} found for DbComputer {} '.format(key, self.name))

def get_workdir(self):
return self._get_val_from_metadata('workdir')

def get_shebang(self):
"""
Return the shebang line
"""
return self._get_val_from_metadata('shebang')

def __str__(self):
if self.enabled:
return "{} ({})".format(self.name, self.hostname)
Expand Down Expand Up @@ -1459,6 +1450,12 @@ def __str__(self):
else:
return "DB authorization info for {} on {} [DISABLED]".format(self.aiidauser.email, self.dbcomputer.name)

def get_aiida_class(self):
from aiida.orm.implementation.django.authinfo import DjangoAuthInfo
from aiida.orm.backends import construct_backend
return DjangoAuthInfo.from_dbmodel(self, construct_backend())



@python_2_unicode_compatible
class DbComment(m.Model):
Expand Down
12 changes: 7 additions & 5 deletions aiida/backends/djsite/db/subtests/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from aiida.backends.testbase import AiidaTestCase
from aiida.common import exceptions
from aiida.orm.node import Node
from aiida import orm


class TestComputer(AiidaTestCase):
Expand All @@ -28,9 +29,9 @@ def test_deletion(self):
from aiida.orm import JobCalculation
from aiida.common.exceptions import InvalidOperation

newcomputer = self.backend.computers.create(name="testdeletioncomputer", hostname='localhost',
transport_type='local', scheduler_type='pbspro',
workdir='/tmp/aiida').store()
newcomputer = orm.Computer(name="testdeletioncomputer", hostname='localhost',
transport_type='local', scheduler_type='pbspro',
workdir='/tmp/aiida').store()

# # This should be possible, because nothing is using this computer
self.backend.computers.delete(newcomputer.id)
Expand Down Expand Up @@ -75,7 +76,7 @@ def test_query(self):
g1.add_nodes([n1, n2])
g2.add_nodes([n1, n3])

newuser = self.backend.users.create(email='test@email.xx')
newuser = orm.User(email='test@email.xx')
g3 = Group(name='testquery3', user=newuser).store()

# I should find it
Expand Down Expand Up @@ -109,7 +110,8 @@ def test_query(self):
res = Group.query(user=newuser.email)
self.assertEquals(set(_.pk for _ in res), set(_.pk for _ in [g3]))

res = Group.query(user=self.backend.users.get_automatic_user())
default_user = orm.User.objects(self.backend).get_default()
res = Group.query(user=default_user.backend_entity)
self.assertEquals(set(_.pk for _ in res), set(_.pk for _ in [g1, g2]))

def test_rename_existing(self):
Expand Down
4 changes: 2 additions & 2 deletions aiida/backends/djsite/db/subtests/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ def test_clsf_django(self):
"""
This tests the classifications of the QueryBuilder u. the django backend.
"""
from aiida.backends.djsite.querybuilder_django.dummy_model import (
from aiida.orm.implementation.django.dummy_model import (
DbNode, DbUser, DbComputer,
DbGroup,
)
from aiida.orm.querybuilder import QueryBuilder
from aiida.orm.data.structure import StructureData
from aiida.orm import Group, Node, Computer, Data, Calculation
from aiida.orm import Group, Node, Computer, Data
from aiida.common.exceptions import InputValidationError
qb = QueryBuilder()

Expand Down
2 changes: 1 addition & 1 deletion aiida/backends/djsite/db/testbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def insert_data(self):
"""
Insert default data into the DB.
"""
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist # pylint: disable=import-error, no-name-in-module

from aiida.backends.djsite.db.models import DbUser
from aiida.common.utils import get_configured_user_email
Expand Down
8 changes: 4 additions & 4 deletions aiida/backends/djsite/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def get_creation_statistics(
an integer with the number of nodes created that day.
"""
import sqlalchemy as sa
from aiida.backends.djsite.querybuilder_django import dummy_model
from aiida.orm.implementation.django import dummy_model

# Get the session (uses internally aldjemy - so, sqlalchemy) also for the Djsite backend
s = dummy_model.get_aldjemy_session()
Expand Down Expand Up @@ -201,16 +201,16 @@ def get_bands_and_parents_structure(self, args):
from django.db.models import Q
from aiida.common.utils import grouper
from aiida.backends.djsite.db import models
from aiida.orm.backend import construct_backend
from aiida.orm.data.structure import (get_formula, get_symbols_string)
from aiida.orm.data.array.bands import BandsData
from aiida import orm

backend = construct_backend()
user = orm.User.objects.get_default()

query_group_size = 100
q_object = None
if args.all_users is False:
q_object = Q(user__id=backend.users.get_automatic_user().id)
q_object = Q(user__id=user.id)
else:
q_object = Q()

Expand Down
9 changes: 0 additions & 9 deletions aiida/backends/djsite/querybuilder_django/__init__.py

This file was deleted.

2 changes: 2 additions & 0 deletions aiida/backends/djsite/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import django
from aiida.common.log import get_dblogger_extra

# pylint: disable=no-name-in-module, no-member, import-error


def load_dbenv(profile=None):
"""
Expand Down
15 changes: 6 additions & 9 deletions aiida/backends/general/abstractqueries.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AbstractQueryManager(object):
def __init__(self, backend):
"""
:param backend: The AiiDA backend
:type backend: :class:`aiida.orm.Backend`
:type backend: :class:`aiida.orm.implementation.backends.Backend`
"""
self._backend = backend

Expand Down Expand Up @@ -81,7 +81,7 @@ def query_jobcalculations_by_computer_user_state(
"""
# I assume that calc_states are strings. If this changes in the future,
# update the filter below from dbattributes__tval to the correct field.
from aiida.orm.computer import Computer
from aiida.orm.computers import Computer
from aiida.orm.calculation.job import JobCalculation
from aiida.orm.querybuilder import QueryBuilder
from aiida.common.exceptions import InputValidationError
Expand Down Expand Up @@ -234,17 +234,14 @@ def get_bands_and_parents_structure(self, args):
from aiida.orm.data.structure import (get_formula, get_symbols_string)
from aiida.orm.data.array.bands import BandsData
from aiida.orm.data.structure import StructureData
from aiida.orm.user import User
from aiida.orm.backend import construct_backend

backend = construct_backend()
from aiida import orm

qb = QueryBuilder()
if args.all_users is False:
user = backend.users.get_automatic_user()
qb.append(User, tag="creator", filters={"email": user.email})
user = orm.User.objects.get_default()
qb.append(orm.User, tag="creator", filters={"email": user.email})
else:
qb.append(User, tag="creator")
qb.append(orm.User, tag="creator")

bdata_filters = {}
if args.past_days is not None:
Expand Down
4 changes: 4 additions & 0 deletions aiida/backends/sqlalchemy/models/authinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ def __str__(self):
return "DB authorization info for {} on {}".format(self.aiidauser.email, self.dbcomputer.name)
else:
return "DB authorization info for {} on {} [DISABLED]".format(self.aiidauser.email, self.dbcomputer.name)

def get_aiida_class(self):
from aiida.orm.implementation.sqlalchemy.authinfo import SqlaAuthInfo
return SqlaAuthInfo.from_dbmodel(dbmodel=self)
25 changes: 6 additions & 19 deletions aiida/backends/sqlalchemy/models/computer.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(self, *args, **kwargs):
self.transport_params = {}
# TODO SP: it's supposed to be nullable, but there is a NOT NULL
# constraint inside the DB.
self.description= ""
self.description = ""

super(DbComputer, self).__init__(*args, **kwargs)

Expand All @@ -61,10 +61,10 @@ def get_dbcomputer(cls, computer):
Return a DbComputer from its name (or from another Computer or DbComputer instance)
"""

from aiida.orm.computer import Computer
from aiida.orm.computers import Computer
if isinstance(computer, six.string_types):
try:
dbcomputer = cls.session.query(cls).filter(cls.name==computer).one()
dbcomputer = cls.session.query(cls).filter(cls.name == computer).one()
except NoResultFound:
raise NotExistent("No computer found in the table of computers with "
"the given name '{}'".format(computer))
Expand All @@ -73,7 +73,7 @@ def get_dbcomputer(cls, computer):
"pass a Computer instance".format(computer))
elif isinstance(computer, int):
try:
dbcomputer = cls.session.query(cls).filter(cls.id==computer).one()
dbcomputer = cls.session.query(cls).filter(cls.id == computer).one()
except NoResultFound:
raise NotExistent("No computer found in the table of computers with "
"the given id '{}'".format(computer))
Expand All @@ -86,28 +86,15 @@ def get_dbcomputer(cls, computer):
raise ValueError("The computer instance you are passing has not been stored yet")
dbcomputer = computer.dbcomputer
else:
raise TypeError("Pass either a computer name, a DbComputer SQLAlchemy instance, a Computer id or a Computer object")
raise TypeError(
"Pass either a computer name, a DbComputer SQLAlchemy instance, a Computer id or a Computer object")
return dbcomputer

def get_aiida_class(self):
from aiida.orm.implementation.sqlalchemy.backend import SqlaBackend
backend = SqlaBackend()
return backend.computers.from_dbmodel(self)

def get_workdir(self):
try:
return self._metadata['workdir']
except KeyError:
raise ConfigurationError('No workdir found for DbComputer {} '.format(
self.name))

def get_shebang(self):
try:
return self._metadata['shebang']
except KeyError:
raise ConfigurationError('No shebang found for DbComputer {} '.format(
self.name))

@property
def pk(self):
return self.id
Expand Down
2 changes: 1 addition & 1 deletion aiida/backends/sqlalchemy/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ def __str__(self):

def get_aiida_class(self):
from aiida.orm.implementation.sqlalchemy.user import SqlaUser
from aiida.orm.backend import construct_backend
from aiida.orm.backends import construct_backend
return SqlaUser.from_dbmodel(self, construct_backend())
Loading