Repository: incubator-ariatosca
Updated Branches:
  refs/heads/SQLAlchemy-based-models c8f0fe26d -> 749f37555


wip


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/749f3755
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/749f3755
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/749f3755

Branch: refs/heads/SQLAlchemy-based-models
Commit: 749f37555f6a60e770018a7dfb5beb178ea0a937
Parents: c8f0fe2
Author: mxmrlv <mxm...@gmail.com>
Authored: Wed Nov 30 19:01:57 2016 +0200
Committer: mxmrlv <mxm...@gmail.com>
Committed: Wed Nov 30 19:01:57 2016 +0200

----------------------------------------------------------------------
 aria/__init__.py                             |  38 +--
 aria/storage/__init__.py                     |  18 +-
 aria/storage/mapi/inmemory.py                |   4 +-
 aria/storage/mapi/sql.py                     |  60 ++--
 aria/storage/models.py                       | 348 +++++++++++-----------
 aria/storage/structures.py                   |  51 +---
 tests/mock/context.py                        |  13 +-
 tests/orchestrator/context/test_operation.py |   4 +-
 tests/orchestrator/context/test_toolbelt.py  |   5 +-
 tests/orchestrator/context/test_workflow.py  |   3 +-
 tests/storage/__init__.py                    |   7 -
 tests/storage/test_model_storage.py          |  51 ++--
 12 files changed, 285 insertions(+), 317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/aria/__init__.py
----------------------------------------------------------------------
diff --git a/aria/__init__.py b/aria/__init__.py
index 374022b..7e7feee 100644
--- a/aria/__init__.py
+++ b/aria/__init__.py
@@ -37,6 +37,7 @@ __all__ = (
     'operation',
 )
 
+_model_storage = {}
 _resource_storage = {}
 
 
@@ -61,23 +62,26 @@ def application_model_storage(api, api_params=None):
     """
     Initiate model storage for the supplied storage driver
     """
-    return storage.ModelStorage(
-        api, api_params=api_params or {}, items=[
-            storage.models.Node,
-            storage.models.Relationship,
-            storage.models.NodeInstance,
-            storage.models.RelationshipInstance,
-            storage.models.Plugin,
-            storage.models.Snapshot,
-            storage.models.Blueprint,
-            storage.models.Deployment,
-            storage.models.DeploymentUpdate,
-            storage.models.DeploymentUpdateStep,
-            storage.models.DeploymentModification,
-            storage.models.Execution,
-            storage.models.ProviderContext,
-            storage.models.Task,
-        ])
+    models = [
+                storage.models.Blueprint,
+                storage.models.Deployment,
+                storage.models.Node,
+                storage.models.NodeInstance,
+                storage.models.Relationship,
+                storage.models.RelationshipInstance,
+                storage.models.Plugin,
+                storage.models.Snapshot,
+                storage.models.DeploymentUpdate,
+                storage.models.DeploymentUpdateStep,
+                storage.models.DeploymentModification,
+                storage.models.Execution,
+                storage.models.ProviderContext,
+                storage.models.Task,
+            ]
+    # if api not in _model_storage:
+    _model_storage[api] = storage.ModelStorage(api, api_params=api_params or 
{}, items=models)
+    return _model_storage[api]
+
 
 
 def application_resource_storage(driver):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/aria/storage/__init__.py
----------------------------------------------------------------------
diff --git a/aria/storage/__init__.py b/aria/storage/__init__.py
index e5b1343..db5caa9 100644
--- a/aria/storage/__init__.py
+++ b/aria/storage/__init__.py
@@ -42,7 +42,6 @@ from aria.logger import LoggerMixin
 from aria.storage import api
 from aria.storage.exceptions import StorageError
 from . import models, exceptions, api, structures
-from .structures import db
 
 
 __all__ = (
@@ -89,13 +88,14 @@ class ResourceStorage(Storage):
 class ModelStorage(Storage):
     def register(self, model):
         model_name = api.generate_lower_name(model)
-        if model_name not in self.registered:
-            self.registered[model_name] = self.api(name=model_name,
-                                                   model_cls=model,
-                                                   **self._api_params)
-            self.registered[model_name].create()
-            self.logger.debug('setup {name} in storage 
{self!r}'.format(name=model_name, self=self))
-        else:
+        if model_name in self.registered:
             self.logger.debug('{name} in already storage 
{self!r}'.format(name=model_name,
                                                                           
self=self))
-
+            return
+        self.registered[model_name] = self.api(name=model_name, 
model_cls=model, **self._api_params)
+        self.registered[model_name].create()
+        self.logger.debug('setup {name} in storage 
{self!r}'.format(name=model_name, self=self))
+
+    def drop(self):
+        for mapi in self.registered.values():
+            mapi.drop()

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/aria/storage/mapi/inmemory.py
----------------------------------------------------------------------
diff --git a/aria/storage/mapi/inmemory.py b/aria/storage/mapi/inmemory.py
index 10c730a..986c43a 100644
--- a/aria/storage/mapi/inmemory.py
+++ b/aria/storage/mapi/inmemory.py
@@ -19,9 +19,9 @@
 
 from collections import namedtuple
 
-from aria.storage.structures import db
 
 from .. import api
+from ..structures import orm
 
 
 _Pointer = namedtuple('_Pointer', 'name, is_iter')
@@ -52,7 +52,7 @@ class InMemoryModelAPI(api.ModelAPI):
     def _setup_pointers_mapping(self):
         for field_name, field_cls in vars(self.model_cls).items():
             if not (getattr(field_cls, 'impl', None) is not None and
-                    isinstance(field_cls.impl.parent_token, 
db.RelationshipProperty)):
+                    isinstance(field_cls.impl.parent_token, 
orm.RelationshipProperty)):
                 continue
             pointer_key = _Pointer(field_name, is_iter=False)
             self.pointer_mapping[pointer_key] = self.__class__(

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/aria/storage/mapi/sql.py
----------------------------------------------------------------------
diff --git a/aria/storage/mapi/sql.py b/aria/storage/mapi/sql.py
index 57f143d..f91d614 100644
--- a/aria/storage/mapi/sql.py
+++ b/aria/storage/mapi/sql.py
@@ -18,9 +18,12 @@ SQLalchemy based MAPI
 from collections import OrderedDict
 
 from sqlite3 import DatabaseError as SQLiteDBError
+from sqlalchemy import create_engine
 from sqlalchemy.exc import SQLAlchemyError
+from sqlalchemy.orm import scoped_session
 from sqlalchemy.sql.elements import Label
 
+
 try:
     from psycopg2 import DatabaseError as Psycopg2DBError
     sql_errors = (SQLAlchemyError, SQLiteDBError, Psycopg2DBError)
@@ -38,21 +41,18 @@ class SQLAlchemyModelAPI(storage.api.ModelAPI):
     """
     SQL based MAPI.
     """
+
     def __init__(self,
-                 app,
-                 sql_dialect=DEFAULT_SQL_DIALECT,
-                 username='',
-                 password='',
-                 host='localhost',
-                 db_name='',
+                 engine,
+                 session,
+                 # sql_dialect=DEFAULT_SQL_DIALECT,
+                 # username='',
+                 # password='',
+                 # host='localhost',
+                 # db_name='',
                  **kwargs):
         super(SQLAlchemyModelAPI, self).__init__(**kwargs)
-        self._app = app
-        self._sql_dialect = sql_dialect
-        self._username = username
-        self._password = password
-        self._host = host
-        self._db_name = db_name
+        self._session = session
 
     def get(self, entry_id, include=None, filters=None, locking=False):
         """Return a single result based on the model class and element ID
@@ -92,7 +92,7 @@ class SQLAlchemyModelAPI(storage.api.ModelAPI):
         of `model_class` (might also my just an instance of `model_class`)
         :return: An instance of `model_class`
         """
-        storage.db.session.add(entry)
+        self._session.add(entry)
         self._safe_commit()
         return entry
 
@@ -113,7 +113,7 @@ class SQLAlchemyModelAPI(storage.api.ModelAPI):
                 )
             )
         self._load_properties(instance)
-        storage.db.session.delete(instance)
+        self._session.delete(instance)
         self._safe_commit()
         return instance
 
@@ -131,7 +131,7 @@ class SQLAlchemyModelAPI(storage.api.ModelAPI):
         :param entry: Instance to be re-loaded from the DB
         :return: The refreshed instance
         """
-        storage.db.session.refresh(entry)
+        self._session.refresh(entry)
         self._load_properties(entry)
         return entry
 
@@ -142,33 +142,19 @@ class SQLAlchemyModelAPI(storage.api.ModelAPI):
         pass
 
     def create(self):
-        if self._app.config.get('SQLALCHEMY_DATABASE_URI', None) is None:
-            sql_uri_template = '{sql_dialect}://'
-            if self._sql_dialect != DEFAULT_SQL_DIALECT:
-                sql_uri_template = sql_uri_template + 
'{username}:{password}@{hostname}/{db_name}'
-            self._app.config['SQLALCHEMY_DATABASE_URI'] = 
sql_uri_template.format(
-                sql_dialect=self._sql_dialect,
-                username=self._username,
-                password=self._password,
-                hostname=self._host,
-                db_name=self._db_name)
-
-        with self._app.app_context():
-            if storage.structures.db.app is None:
-                storage.structures.db.app = self._app
-                storage.structures.db.init_app(self._app)
-            self.model_cls.__table__.create(storage.structures.db.session.bind)
+        self.model_cls.__table__.create(self._engine)
 
+    def drop(self):
+        self.model_cls.__table__.drop(self._engine)
 
-    @staticmethod
-    def _safe_commit():
+    def _safe_commit(self):
         """Try to commit changes in the session. Roll back if exception raised
         Excepts SQLAlchemy errors and rollbacks if they're caught
         """
         try:
-            storage.db.session.commit()
+            self._session.commit()
         except sql_errors as e:
-            storage.db.session.rollback()
+            self._session.rollback()
             raise storage.exceptions.StorageError(
                 'SQL Storage error: {0}'.format(str(e))
             )
@@ -185,10 +171,10 @@ class SQLAlchemyModelAPI(storage.api.ModelAPI):
 
         # If only some columns are included, query through the session object
         if include:
-            query = storage.db.session.query(*include)
+            query = self._session.query(*include)
         else:
             # If all columns should be returned, query directly from the model
-            query = self.model_cls.query
+            query = self._session.query(self.model_cls)
 
         # Add any joins that might be necessary
         for join_model in joins:

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/aria/storage/models.py
----------------------------------------------------------------------
diff --git a/aria/storage/models.py b/aria/storage/models.py
index 5a8d017..55b9247 100644
--- a/aria/storage/models.py
+++ b/aria/storage/models.py
@@ -39,9 +39,9 @@ classes:
 from datetime import datetime
 from uuid import uuid4
 
-from aria.storage import structures
 from .structures import (
-    schema,
+    SQLModelBase,
+    Column,
     Integer,
     Text,
     DateTime,
@@ -50,6 +50,10 @@ from .structures import (
     String,
     PickleType,
     Float,
+    MutableDict,    
+    Dict,
+    foreign_key,
+    one_to_many_relationship
 )
 
 __all__ = (
@@ -81,23 +85,23 @@ def uuid_generator():
     return str(uuid4())
 
 
-class Blueprint(structures.SQLModelBase):
+class Blueprint(SQLModelBase):
     """
     Blueprint model representation.
     """
     __tablename__ = 'blueprints'
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    created_at = schema.Column(DateTime, nullable=False, index=True)
-    main_file_name = schema.Column(Text, nullable=False)
-    plan = schema.Column(structures.MutableDict.as_mutable(structures.Dict), 
nullable=False)
-    updated_at = schema.Column(DateTime)
-    description = schema.Column(Text)
+    created_at = Column(DateTime, nullable=False, index=True)
+    main_file_name = Column(Text, nullable=False)
+    plan = Column(MutableDict.as_mutable(Dict), nullable=False)
+    updated_at = Column(DateTime)
+    description = Column(Text)
 
 
-class Snapshot(structures.SQLModelBase):
+class Snapshot(SQLModelBase):
     """
     Snapshot model representation.
     """
@@ -111,15 +115,15 @@ class Snapshot(structures.SQLModelBase):
     STATES = [CREATED, FAILED, CREATING, UPLOADED]
     END_STATES = [CREATED, FAILED, UPLOADED]
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    created_at = schema.Column(DateTime, nullable=False, index=True)
-    status = schema.Column(Enum(*STATES, name='snapshot_status'))
-    error = schema.Column(Text)
+    created_at = Column(DateTime, nullable=False, index=True)
+    status = Column(Enum(*STATES, name='snapshot_status'))
+    error = Column(Text)
 
 
-class Deployment(structures.SQLModelBase):
+class Deployment(SQLModelBase):
     """
     Deployment model representation.
     """
@@ -137,23 +141,23 @@ class Deployment(structures.SQLModelBase):
 
     _private_fields = ['blueprint_storage_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
-
-    created_at = schema.Column(DateTime, nullable=False, index=True)
-    description = schema.Column(Text)
-    inputs = schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    groups = schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    permalink = schema.Column(Text)
-    policy_triggers = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    policy_types = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    outputs = schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    scaling_groups = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    updated_at = schema.Column(DateTime)
-    workflows = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-
-    blueprint_storage_id = structures.foreign_key(Blueprint)
-    blueprint = structures.one_to_many_relationship(
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
+
+    created_at = Column(DateTime, nullable=False, index=True)
+    description = Column(Text)
+    inputs = Column(MutableDict.as_mutable(Dict))
+    groups = Column(MutableDict.as_mutable(Dict))
+    permalink = Column(Text)
+    policy_triggers = Column(MutableDict.as_mutable(Dict))
+    policy_types = Column(MutableDict.as_mutable(Dict))
+    outputs = Column(MutableDict.as_mutable(Dict))
+    scaling_groups = Column(MutableDict.as_mutable(Dict))
+    updated_at = Column(DateTime)
+    workflows = Column(MutableDict.as_mutable(Dict))
+
+    blueprint_storage_id = foreign_key(Blueprint)
+    blueprint = one_to_many_relationship(
         child_class_name='Deployment',
         column_name='blueprint_storage_id',
         parent_class_name='Blueprint',
@@ -169,7 +173,7 @@ class Deployment(structures.SQLModelBase):
         return self.blueprint.id
 
 
-class Execution(structures.SQLModelBase):
+class Execution(SQLModelBase):
     """
     Execution model representation.
     """
@@ -203,20 +207,20 @@ class Execution(structures.SQLModelBase):
 
     _private_fields = ['deployment_storage_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    created_at = schema.Column(DateTime, index=True)
-    started_at = schema.Column(DateTime, nullable=True, index=True)
-    ended_at = schema.Column(DateTime, nullable=True, index=True)
-    error = schema.Column(Text, nullable=True)
-    is_system_workflow = schema.Column(Boolean, nullable=False, default=False)
-    parameters = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    status = schema.Column(Enum(*STATES, name='execution_status'))
-    workflow_id = schema.Column(Text, nullable=False)
+    created_at = Column(DateTime, index=True)
+    started_at = Column(DateTime, nullable=True, index=True)
+    ended_at = Column(DateTime, nullable=True, index=True)
+    error = Column(Text, nullable=True)
+    is_system_workflow = Column(Boolean, nullable=False, default=False)
+    parameters = Column(MutableDict.as_mutable(Dict))
+    status = Column(Enum(*STATES, name='execution_status'))
+    workflow_id = Column(Text, nullable=False)
 
-    deployment_storage_id = structures.foreign_key(Deployment, nullable=True)
-    deployment = structures.one_to_many_relationship(
+    deployment_storage_id = foreign_key(Deployment, nullable=True)
+    deployment = one_to_many_relationship(
         child_class_name='Execution',
         column_name='deployment_storage_id',
         parent_class_name='Deployment',
@@ -249,7 +253,7 @@ class Execution(structures.SQLModelBase):
         )
 
 
-class DeploymentUpdate(structures.SQLModelBase):
+class DeploymentUpdate(SQLModelBase):
     """
     Deployment update model representation.
     """
@@ -270,28 +274,28 @@ class DeploymentUpdate(structures.SQLModelBase):
 
     _private_fields = ['execution_storage_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    created_at = schema.Column(DateTime, nullable=False, index=True)
-    deployment_plan = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    deployment_update_node_instances = 
schema.Column(structures.MutableDict.as_mutable(
-        structures.Dict))
-    deployment_update_deployment = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    deployment_update_nodes = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    modified_entity_ids = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    state = schema.Column(Text)
+    created_at = Column(DateTime, nullable=False, index=True)
+    deployment_plan = Column(MutableDict.as_mutable(Dict))
+    deployment_update_node_instances = Column(MutableDict.as_mutable(
+        Dict))
+    deployment_update_deployment = Column(MutableDict.as_mutable(Dict))
+    deployment_update_nodes = Column(MutableDict.as_mutable(Dict))
+    modified_entity_ids = Column(MutableDict.as_mutable(Dict))
+    state = Column(Text)
 
-    execution_storage_id = structures.foreign_key(Execution, nullable=True)
-    execution = structures.one_to_many_relationship(
+    execution_storage_id = foreign_key(Execution, nullable=True)
+    execution = one_to_many_relationship(
         child_class_name='DeploymentUpdate',
         column_name='execution_storage_id',
         parent_class_name='Execution',
         back_reference_name='deployment_updates'
     )
 
-    deployment_storage_id = structures.foreign_key(Deployment)
-    deployment = structures.one_to_many_relationship(
+    deployment_storage_id = foreign_key(Deployment)
+    deployment = one_to_many_relationship(
         child_class_name='DeploymentUpdate',
         column_name='deployment_storage_id',
         parent_class_name='Deployment',
@@ -321,7 +325,7 @@ class DeploymentUpdate(structures.SQLModelBase):
         return dep_update_dict
 
 
-class DeploymentUpdateStep(structures.SQLModelBase):
+class DeploymentUpdateStep(SQLModelBase):
     """
     Deployment update step model representation.
     """
@@ -338,14 +342,14 @@ class DeploymentUpdateStep(structures.SQLModelBase):
 
     _private_fields = ['deployment_update_storage_id']
 
-    id = schema.Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Integer, primary_key=True, autoincrement=True)
 
-    action = schema.Column(Enum(*ACTION_TYPES, name='action_type'))
-    entity_id = schema.Column(Text, nullable=False)
-    entity_type = schema.Column(Enum(*ENTITY_TYPES, name='entity_type'))
+    action = Column(Enum(*ACTION_TYPES, name='action_type'))
+    entity_id = Column(Text, nullable=False)
+    entity_type = Column(Enum(*ENTITY_TYPES, name='entity_type'))
 
-    deployment_update_storage_id = structures.foreign_key(DeploymentUpdate)
-    deployment_update = structures.one_to_many_relationship(
+    deployment_update_storage_id = foreign_key(DeploymentUpdate)
+    deployment_update = one_to_many_relationship(
         child_class_name='DeploymentUpdateStep',
         column_name='deployment_update_storage_id',
         parent_class_name='DeploymentUpdate',
@@ -361,7 +365,7 @@ class DeploymentUpdateStep(structures.SQLModelBase):
         return self.deployment_update.id
 
 
-class DeploymentModification(structures.SQLModelBase):
+class DeploymentModification(SQLModelBase):
     """
     Deployment modification model representation.
     """
@@ -385,19 +389,19 @@ class DeploymentModification(structures.SQLModelBase):
 
     _private_fields = ['deployment_storage_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    context = schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    created_at = schema.Column(DateTime, nullable=False, index=True)
-    ended_at = schema.Column(DateTime, index=True)
-    modified_nodes = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    node_instances = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    status = schema.Column(
+    context = Column(MutableDict.as_mutable(Dict))
+    created_at = Column(DateTime, nullable=False, index=True)
+    ended_at = Column(DateTime, index=True)
+    modified_nodes = Column(MutableDict.as_mutable(Dict))
+    node_instances = Column(MutableDict.as_mutable(Dict))
+    status = Column(
         Enum(*STATES, name='deployment_modification_status'))
 
-    deployment_storage_id = structures.foreign_key(Deployment)
-    deployment = structures.one_to_many_relationship(
+    deployment_storage_id = foreign_key(Deployment)
+    deployment = one_to_many_relationship(
         child_class_name='DeploymentModification',
         column_name='deployment_storage_id',
         parent_class_name='Deployment',
@@ -413,7 +417,7 @@ class DeploymentModification(structures.SQLModelBase):
         return self.deployment.id
 
 
-class Node(structures.SQLModelBase):
+class Node(SQLModelBase):
     """
     Node model representation.
     """
@@ -435,26 +439,26 @@ class Node(structures.SQLModelBase):
 
     _private_fields = ['deployment_storage_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    deploy_number_of_instances = schema.Column(Integer, nullable=False)
+    deploy_number_of_instances = Column(Integer, nullable=False)
     # TODO: This probably should be a foreign key, but there's no guarantee
     # in the code, currently, that the host will be created beforehand
-    host_id = schema.Column(Text)
-    max_number_of_instances = schema.Column(Integer, nullable=False)
-    min_number_of_instances = schema.Column(Integer, nullable=False)
-    number_of_instances = schema.Column(Integer, nullable=False)
-    planned_number_of_instances = schema.Column(Integer, nullable=False)
-    plugins = schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    plugins_to_install = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    properties = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    operations = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    type = schema.Column(Text, nullable=False, index=True)
-    type_hierarchy = schema.Column(PickleType)
-
-    deployment_storage_id = structures.foreign_key(Deployment)
-    deployment = structures.one_to_many_relationship(
+    host_id = Column(Text)
+    max_number_of_instances = Column(Integer, nullable=False)
+    min_number_of_instances = Column(Integer, nullable=False)
+    number_of_instances = Column(Integer, nullable=False)
+    planned_number_of_instances = Column(Integer, nullable=False)
+    plugins = Column(MutableDict.as_mutable(Dict))
+    plugins_to_install = Column(MutableDict.as_mutable(Dict))
+    properties = Column(MutableDict.as_mutable(Dict))
+    operations = Column(MutableDict.as_mutable(Dict))
+    type = Column(Text, nullable=False, index=True)
+    type_hierarchy = Column(PickleType)
+
+    deployment_storage_id = foreign_key(Deployment)
+    deployment = one_to_many_relationship(
         child_class_name='Node',
         column_name='deployment_storage_id',
         parent_class_name='Deployment',
@@ -478,7 +482,7 @@ class Node(structures.SQLModelBase):
         return self.deployment.blueprint_id
 
 
-class Relationship(structures.SQLModelBase):
+class Relationship(SQLModelBase):
     """
     Relationship model representation.
     """
@@ -498,27 +502,27 @@ class Relationship(structures.SQLModelBase):
     _private_fields = ['relationship_storage_source_node_id',
                        'relationship_storage_target_node_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    source_interfaces = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    source_operations = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    target_interfaces = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    target_operations = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    type = schema.Column(String)
-    type_hierarchy = schema.Column(PickleType)     # TODO: this should be list
-    properties = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
+    source_interfaces = Column(MutableDict.as_mutable(Dict))
+    source_operations = Column(MutableDict.as_mutable(Dict))
+    target_interfaces = Column(MutableDict.as_mutable(Dict))
+    target_operations = Column(MutableDict.as_mutable(Dict))
+    type = Column(String)
+    type_hierarchy = Column(PickleType)     # TODO: this should be list
+    properties = Column(MutableDict.as_mutable(Dict))
 
-    source_node_storage_id = structures.foreign_key(Node)
-    target_node_storage_id = structures.foreign_key(Node)
+    source_node_storage_id = foreign_key(Node)
+    target_node_storage_id = foreign_key(Node)
 
-    source_node = structures.one_to_many_relationship(
+    source_node = one_to_many_relationship(
         child_class_name='Relationship',
         column_name='source_node_storage_id',
         parent_class_name='Node',
         back_reference_name='relationship_source'
     )
-    target_node = structures.one_to_many_relationship(
+    target_node = one_to_many_relationship(
         child_class_name='Relationship',
         column_name='target_node_storage_id',
         parent_class_name='Node',
@@ -526,7 +530,7 @@ class Relationship(structures.SQLModelBase):
     )
 
 
-class NodeInstance(structures.SQLModelBase):
+class NodeInstance(SQLModelBase):
     """
     Node instance model representation.
     """
@@ -547,19 +551,19 @@ class NodeInstance(structures.SQLModelBase):
 
     _private_fields = ['node_storage_id', 'deployment_storage_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
     # TODO: This probably should be a foreign key, but there's no guarantee
     # in the code, currently, that the host will be created beforehand
-    host_id = schema.Column(Text)
-    runtime_properties = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    scaling_groups = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    state = schema.Column(Text, nullable=False)
-    version = schema.Column(Integer, default=1)
-
-    node_storage_id = structures.foreign_key(Node)
-    node = structures.one_to_many_relationship(
+    host_id = Column(Text)
+    runtime_properties = Column(MutableDict.as_mutable(Dict))
+    scaling_groups = Column(MutableDict.as_mutable(Dict))
+    state = Column(Text, nullable=False)
+    version = Column(Integer, default=1)
+
+    node_storage_id = foreign_key(Node)
+    node = one_to_many_relationship(
         child_class_name='NodeInstance',
         column_name='node_storage_id',
         parent_class_name='Node',
@@ -574,8 +578,8 @@ class NodeInstance(structures.SQLModelBase):
         """
         return self.node.id
 
-    deployment_storage_id = structures.foreign_key(Deployment)
-    deployment = structures.one_to_many_relationship(
+    deployment_storage_id = foreign_key(Deployment)
+    deployment = one_to_many_relationship(
         child_class_name='NodeInstance',
         column_name='deployment_storage_id',
         parent_class_name='Deployment',
@@ -583,7 +587,7 @@ class NodeInstance(structures.SQLModelBase):
     )
 
 
-class RelationshipInstance(structures.SQLModelBase):
+class RelationshipInstance(SQLModelBase):
     """
     Relationship instance model representation.
     """
@@ -605,27 +609,27 @@ class RelationshipInstance(structures.SQLModelBase):
                        'source_node_instance_id',
                        'target_node_instance_id']
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    type = schema.Column(String)
+    type = Column(String)
 
-    source_node_instance_storage_id = structures.foreign_key(NodeInstance)
-    source_node_instance = structures.one_to_many_relationship(
+    source_node_instance_storage_id = foreign_key(NodeInstance)
+    source_node_instance = one_to_many_relationship(
         child_class_name='RelationshipInstance',
         column_name='source_node_instance_storage_id',
         parent_class_name='NodeInstance',
         back_reference_name='relationship_instance_source'
     )
-    target_node_instance_storage_id = structures.foreign_key(NodeInstance)
-    target_node_instance = structures.one_to_many_relationship(
+    target_node_instance_storage_id = foreign_key(NodeInstance)
+    target_node_instance = one_to_many_relationship(
         child_class_name='RelationshipInstance',
         column_name='target_node_instance_storage_id',
         parent_class_name='NodeInstance',
         back_reference_name='relationship_instance_target'
     )
-    relationship_storage_id = structures.foreign_key(Relationship)
-    relationship = structures.one_to_many_relationship(
+    relationship_storage_id = foreign_key(Relationship)
+    relationship = one_to_many_relationship(
         child_class_name='RelationshipInstance',
         column_name='relationship_storage_id',
         parent_class_name='Relationship',
@@ -633,41 +637,41 @@ class RelationshipInstance(structures.SQLModelBase):
     )
 
 
-class ProviderContext(structures.SQLModelBase):
+class ProviderContext(SQLModelBase):
     """
     Provider context model representation.
     """
     __tablename__ = 'provider_context'
 
-    id = schema.Column(Text, primary_key=True)
-    name = schema.Column(Text, nullable=False)
-    context = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict), 
nullable=False)
+    id = Column(Text, primary_key=True)
+    name = Column(Text, nullable=False)
+    context = Column(MutableDict.as_mutable(Dict), nullable=False)
 
 
-class Plugin(structures.SQLModelBase):
+class Plugin(SQLModelBase):
     """
     Plugin model representation.
     """
     __tablename__ = 'plugins'
 
-    storage_id = schema.Column(Integer, primary_key=True, autoincrement=True)
-    id = schema.Column(Text, index=True)
+    storage_id = Column(Integer, primary_key=True, autoincrement=True)
+    id = Column(Text, index=True)
 
-    archive_name = schema.Column(Text, nullable=False, index=True)
-    distribution = schema.Column(Text)
-    distribution_release = schema.Column(Text)
-    distribution_version = schema.Column(Text)
-    excluded_wheels = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    package_name = schema.Column(Text, nullable=False, index=True)
-    package_source = schema.Column(Text)
-    package_version = schema.Column(Text)
-    supported_platform = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    supported_py_versions = 
schema.Column(structures.MutableDict.as_mutable(structures.Dict))
-    uploaded_at = schema.Column(DateTime, nullable=False, index=True)
-    wheels = schema.Column(structures.MutableDict.as_mutable(structures.Dict), 
nullable=False)
+    archive_name = Column(Text, nullable=False, index=True)
+    distribution = Column(Text)
+    distribution_release = Column(Text)
+    distribution_version = Column(Text)
+    excluded_wheels = Column(MutableDict.as_mutable(Dict))
+    package_name = Column(Text, nullable=False, index=True)
+    package_source = Column(Text)
+    package_version = Column(Text)
+    supported_platform = Column(MutableDict.as_mutable(Dict))
+    supported_py_versions = Column(MutableDict.as_mutable(Dict))
+    uploaded_at = Column(DateTime, nullable=False, index=True)
+    wheels = Column(MutableDict.as_mutable(Dict), nullable=False)
 
 
-class Task(structures.SQLModelBase):
+class Task(SQLModelBase):
     """
     A Model which represents an task
     """
@@ -705,35 +709,35 @@ class Task(structures.SQLModelBase):
 
     INFINITE_RETRIES = -1
 
-    id = schema.Column(String, primary_key=True, default=uuid_generator)
-    status = schema.Column(Enum(*STATES), name='status', default=PENDING)
+    id = Column(String, primary_key=True, default=uuid_generator)
+    status = Column(Enum(*STATES), name='status', default=PENDING)
 
-    execution_id = schema.Column(String)
-    due_at = schema.Column(DateTime, default=datetime.utcnow, nullable=True)
-    started_at = schema.Column(DateTime, default=None, nullable=True)
-    ended_at = schema.Column(DateTime, default=None, nullable=True)
+    execution_id = Column(String)
+    due_at = Column(DateTime, default=datetime.utcnow, nullable=True)
+    started_at = Column(DateTime, default=None, nullable=True)
+    ended_at = Column(DateTime, default=None, nullable=True)
     # , validation_func=_Validation.validate_max_attempts)
-    max_attempts = schema.Column(Integer, default=1)
-    retry_count = schema.Column(Integer, default=0)
-    retry_interval = schema.Column(Float, default=0)
-    ignore_failure = schema.Column(Boolean, default=False)
+    max_attempts = Column(Integer, default=1)
+    retry_count = Column(Integer, default=0)
+    retry_interval = Column(Float, default=0)
+    ignore_failure = Column(Boolean, default=False)
 
     # Operation specific fields
-    name = schema.Column(String)
-    operation_mapping = schema.Column(String)
-    inputs = schema.Column(structures.MutableDict.as_mutable(structures.Dict))
+    name = Column(String)
+    operation_mapping = Column(String)
+    inputs = Column(MutableDict.as_mutable(Dict))
 
-    node_instance_storage_id = structures.foreign_key(NodeInstance, 
nullable=True)
-    relationship_instance_storage_id = 
structures.foreign_key(RelationshipInstance, nullable=True)
+    node_instance_storage_id = foreign_key(NodeInstance, nullable=True)
+    relationship_instance_storage_id = foreign_key(RelationshipInstance, 
nullable=True)
 
-    node_instance = structures.one_to_many_relationship(
+    node_instance = one_to_many_relationship(
         child_class_name='Task',
         column_name='node_instance_storage_id',
         parent_class_name='NodeInstance',
         back_reference_name='tasks',
     )
 
-    relationship_instance = structures.one_to_many_relationship(
+    relationship_instance = one_to_many_relationship(
         child_class_name='Task',
         column_name='relationship_instance_storage_id',
         parent_class_name='RelationshipInstance',

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/aria/storage/structures.py
----------------------------------------------------------------------
diff --git a/aria/storage/structures.py b/aria/storage/structures.py
index 92434d6..4d86bf8 100644
--- a/aria/storage/structures.py
+++ b/aria/storage/structures.py
@@ -29,11 +29,13 @@ classes:
 import json
 
 import jsonpickle
-from flask_sqlalchemy import SQLAlchemy
+from sqlalchemy import VARCHAR
 from sqlalchemy.ext.mutable import Mutable
+from sqlalchemy.ext.declarative import declarative_base
 # pylint: disable=unused-import
 from sqlalchemy import (
     schema,
+    Column,
     Integer,
     Text,
     DateTime,
@@ -43,13 +45,12 @@ from sqlalchemy import (
     PickleType,
     Float,
     TypeDecorator,
-    ForeignKey
+    ForeignKey,
+    orm,
 )
 
 
-
-db = SQLAlchemy()
-
+Model = declarative_base()
 
 class classproperty(object):
     """A class that acts a a decorator for class-level properties
@@ -87,7 +88,7 @@ def foreign_key(
     :param column_type: The type (integer/text/etc.) of the column
     :return:
     """
-    return db.Column(
+    return Column(
         column_type,
         ForeignKey(
             '{0}.{1}'.format(parent_table.__tablename__, id_col_name),
@@ -114,7 +115,7 @@ def one_to_many_relationship(
     :param parent_id_name: Name of the parent table's ID column [default: `id`]
     :return:
     """
-    return db.relationship(
+    return orm.relationship(
         parent_class_name,
         primaryjoin='{0}.{1} == {2}.{3}'.format(
             child_class_name,
@@ -124,7 +125,7 @@ def one_to_many_relationship(
         ),
         # The following line make sure that when the *parent* is
         # deleted, all its connected children are deleted as well
-        backref=db.backref(back_reference_name, cascade='all')
+        backref=orm.backref(back_reference_name, cascade='all')
     )
 
 
@@ -141,42 +142,19 @@ def many_to_many_relationship(
     current table from the other table
     :return:
     """
-    return db.relationship(
+    return orm.relationship(
         other_table_class_name,
         secondary=connecting_table,
-        backref=db.backref(back_reference_name, lazy='dynamic')
+        backref=orm.backref(back_reference_name, lazy='dynamic')
     )
 
 
-# class UTCDateTime(TypeDecorator):
-#
-#     impl = db.DateTime
-#
-#     def process_result_value(self, value, engine):
-#         # Adhering to the same norms used in the rest of the code
-#         if value is not None:
-#             # When the date has a microsecond value equal to 0,
-#             # isoformat returns the time as 17:22:11 instead of
-#             # 17:22:11.000, so we need to adjust the returned value
-#             if value.microsecond:
-#                 return '{0}Z'.format(value.isoformat()[:-3])
-#             else:
-#                 return '{0}.000Z'.format(value.isoformat())
-#
-#     def process_bind_param(self, value, dialect):
-#         if isinstance(value, basestring):
-#             # SQLite only accepts datetime objects
-#             return date_parser.parse(value)
-#         else:
-#             return value
-
-
 class Dict(TypeDecorator):
     """
     Dict represenation of type.
     """
 
-    impl = db.VARCHAR
+    impl = VARCHAR
 
     def process_bind_param(self, value, dialect):
         if value is not None:
@@ -219,7 +197,7 @@ class MutableDict(Mutable, dict):
         self.changed()
 
 
-class SQLModelBase(db.Model):
+class SQLModelBase(Model):
     """Abstract base class for all SQL models that allows [de]serialization
     """
     # SQLAlchemy syntax
@@ -274,3 +252,6 @@ class SQLModelBase(db.Model):
 
     def __unicode__(self):
         return str(self)
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self.to_dict == 
other.to_dict

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/tests/mock/context.py
----------------------------------------------------------------------
diff --git a/tests/mock/context.py b/tests/mock/context.py
index 54e877c..7f09b75 100644
--- a/tests/mock/context.py
+++ b/tests/mock/context.py
@@ -14,20 +14,25 @@
 # limitations under the License.
 
 import pytest
-from flask import Flask
+from sqlalchemy import create_engine, orm
 
 from aria import application_model_storage
 from aria.orchestrator import context
 from aria.storage.mapi import SQLAlchemyModelAPI
 
-from tests import storage
 from . import models
 
 
 @pytest.fixture
 def simple(**kwargs):
-    storage.drop_tables()
-    model_storage = application_model_storage(SQLAlchemyModelAPI, 
api_params=dict(app=Flask('app')))
+    engine = create_engine('sqlite:///:memory:')
+    model_storage = application_model_storage(
+        SQLAlchemyModelAPI,
+        api_params={
+            'engine': engine,
+            'session': orm.sessionmaker(bind=engine)()
+        }
+    )
     model_storage.blueprint.store(models.get_blueprint())
     blueprint = model_storage.blueprint.get(models.BLUEPRINT_ID)
     deployment = models.get_deployment(blueprint)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py 
b/tests/orchestrator/context/test_operation.py
index 4f52577..ec13154 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -35,7 +35,9 @@ global_test_holder = {}
 
 @pytest.fixture
 def ctx():
-    return mock.context.simple()
+    context = mock.context.simple()
+    yield context
+    context.model.drop()
 
 
 @pytest.fixture

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/tests/orchestrator/context/test_toolbelt.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_toolbelt.py 
b/tests/orchestrator/context/test_toolbelt.py
index dc06c4e..d5297ce 100644
--- a/tests/orchestrator/context/test_toolbelt.py
+++ b/tests/orchestrator/context/test_toolbelt.py
@@ -33,8 +33,9 @@ global_test_holder = {}
 
 @pytest.fixture
 def workflow_context():
-    return mock.context.simple()
-
+    context = mock.context.simple()
+    yield context
+    context.model.drop()
 
 @pytest.fixture
 def executor():

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/tests/orchestrator/context/test_workflow.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_workflow.py 
b/tests/orchestrator/context/test_workflow.py
index f385b93..03648f1 100644
--- a/tests/orchestrator/context/test_workflow.py
+++ b/tests/orchestrator/context/test_workflow.py
@@ -59,8 +59,7 @@ class TestWorkflowContext(object):
 
 @pytest.fixture(scope='function')
 def storage():
-    test_storage.drop_tables()
-    result = application_model_storage(SQLAlchemyModelAPI, 
api_params=dict(app=Flask('app')))
+    result = application_model_storage(SQLAlchemyModelAPI)
     result.blueprint.store(models.get_blueprint())
     blueprint = result.blueprint.get(models.BLUEPRINT_ID)
     result.deployment.store(models.get_deployment(blueprint))

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/tests/storage/__init__.py
----------------------------------------------------------------------
diff --git a/tests/storage/__init__.py b/tests/storage/__init__.py
index 5cbdc6a..f5939da 100644
--- a/tests/storage/__init__.py
+++ b/tests/storage/__init__.py
@@ -16,8 +16,6 @@
 from shutil import rmtree
 from tempfile import mkdtemp
 
-from aria import storage
-
 
 class TestFileSystem(object):
 
@@ -26,8 +24,3 @@ class TestFileSystem(object):
 
     def teardown_method(self):
         rmtree(self.path)
-
-
-def drop_tables():
-    if storage.structures.db.app is not None:
-        storage.structures.db.drop_all(bind=None)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/749f3755/tests/storage/test_model_storage.py
----------------------------------------------------------------------
diff --git a/tests/storage/test_model_storage.py 
b/tests/storage/test_model_storage.py
index 9723afc..6e36f84 100644
--- a/tests/storage/test_model_storage.py
+++ b/tests/storage/test_model_storage.py
@@ -17,7 +17,6 @@ import tempfile
 import shutil
 
 import pytest
-from flask import Flask
 
 from aria import application_model_storage
 
@@ -34,8 +33,8 @@ from . import drop_tables
 temp_dir = tempfile.mkdtemp()
 
 APIs = [
-    # (storage_api.FileSystemModelAPI, dict(directory=temp_dir)),
-    (storage_api.SQLAlchemyModelAPI, dict(app=Flask('app')))
+    ModelStorage(storage_api.SQLAlchemyModelAPI),
+    # ModelStorage(storage_api.FileSystemModelAPI, 
api_params=dict(directory=temp_dir)),
 ]
 
 
@@ -49,19 +48,14 @@ def cleanup():
         pass
 
 
-@pytest.mark.parametrize('api, api_params', APIs)
-def test_storage_base(api, api_params):
-    storage = ModelStorage(api, api_params=api_params)
-
-    assert storage.api == api
-
+@pytest.mark.parametrize('storage', APIs)
+def test_storage_base(storage):
     with pytest.raises(AttributeError):
         storage.non_existent_attribute()
 
 
-@pytest.mark.parametrize('api, api_params', APIs)
-def test_model_storage(api, api_params):
-    storage = ModelStorage(api, api_params=api_params)
+@pytest.mark.parametrize('storage', APIs)
+def test_model_storage(storage):
     storage.register(models.ProviderContext)
 
     pc = models.ProviderContext(context={}, name='context_name', id='id1')
@@ -82,9 +76,8 @@ def test_model_storage(api, api_params):
         storage.provider_context.get('id1')
 
 
-@pytest.mark.parametrize('api, api_params', APIs)
-def test_storage_driver(api, api_params):
-    storage = ModelStorage(api, api_params=api_params)
+@pytest.mark.parametrize('storage', APIs)
+def test_storage_driver(storage):
     storage.register(models.ProviderContext)
 
     pc = models.ProviderContext(context={}, name='context_name', id='id2')
@@ -101,17 +94,17 @@ def test_storage_driver(api, api_params):
         storage.registered['provider_context'].get('id2')
 
 
-@pytest.mark.parametrize('api, api_params', APIs)
-def test_application_storage_factory(api, api_params):
-    storage = application_model_storage(api, api_params=api_params)
-    assert storage.node
-    assert storage.node_instance
-    assert storage.plugin
-    assert storage.blueprint
-    assert storage.snapshot
-    assert storage.deployment
-    assert storage.deployment_update
-    assert storage.deployment_update_step
-    assert storage.deployment_modification
-    assert storage.execution
-    assert storage.provider_context
+# @pytest.mark.parametrize('storage', APIs)
+# def test_application_storage_factory(storage):
+#     storage = application_model_storage(api, api_params=api_params)
+#     assert storage.node
+#     assert storage.node_instance
+#     assert storage.plugin
+#     assert storage.blueprint
+#     assert storage.snapshot
+#     assert storage.deployment
+#     assert storage.deployment_update
+#     assert storage.deployment_update_step
+#     assert storage.deployment_modification
+#     assert storage.execution
+#     assert storage.provider_context


Reply via email to