From 82e317740443ee927d487440975876d6eb281e3f Mon Sep 17 00:00:00 2001 From: Felipe Monteiro Date: Wed, 19 Jul 2017 22:40:18 +0100 Subject: [PATCH] Successfully creating document. TODO: clean up dummy test code and move registration of DB tables to app initialization. TODO: update documentation TODO: include unit tests To create a document: 1) run tox -egenconfig 2) rename the configured file from deckhand.conf.sample to deckhand.conf and place it in, e.g., ~/deckhand 3) include in deckhand.conf: [database] connection = sqlite:///:memory: to create an in-memory test db --- deckhand/db/sqlalchemy/api.py | 12 ++++++++++-- deckhand/db/sqlalchemy/models.py | 28 ++++++++++++++++++++++++---- deckhand/objects/documents.py | 15 ++++----------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/deckhand/db/sqlalchemy/api.py b/deckhand/db/sqlalchemy/api.py index a6ee3341..71580607 100644 --- a/deckhand/db/sqlalchemy/api.py +++ b/deckhand/db/sqlalchemy/api.py @@ -34,6 +34,7 @@ import sqlalchemy.orm as sa_orm from sqlalchemy import sql import sqlalchemy.sql as sa_sql +from deckhand.db.sqlalchemy import models sa_logger = None LOG = logging.getLogger(__name__) @@ -96,6 +97,13 @@ def clear_db_env(): _FACADE = None -def image_create(context): +def document_create(context, values, session=None): """Create a document.""" - pass + models.register_models(get_engine()) + + values = values.copy() + session = session or get_session() + with session.begin(): + document = models.Document() + document.update(values) + document.save(session=session) diff --git a/deckhand/db/sqlalchemy/models.py b/deckhand/db/sqlalchemy/models.py index 457e715b..cb75e5eb 100644 --- a/deckhand/db/sqlalchemy/models.py +++ b/deckhand/db/sqlalchemy/models.py @@ -12,16 +12,21 @@ # See the License for the specific language governing permissions and # limitations under the License. +import uuid + from oslo_db.sqlalchemy import models from oslo_serialization import jsonutils as json from oslo_utils import timeutils +from sqlalchemy import Boolean from sqlalchemy import Column +from sqlalchemy import DateTime from sqlalchemy.ext import declarative from sqlalchemy import Integer from sqlalchemy import orm from sqlalchemy import schema from sqlalchemy import String from sqlalchemy import Text +from sqlalchemy.types import TypeDecorator # Declarative base class which maintains a catalog of classes and tables @@ -29,7 +34,7 @@ from sqlalchemy import Text BASE = declarative.declarative_base() -class JSONEncodedDict(types.TypeDecorator): +class JSONEncodedDict(TypeDecorator): """Represents an immutable structure as a json-encoded string. Usage:: @@ -68,7 +73,7 @@ class DeckhandBase(models.ModelBase, models.TimestampMixin): nullable=False) updated_at = Column(DateTime, default=lambda: timeutils.utcnow(), nullable=True, onupdate=lambda: timeutils.utcnow()) - deleted_at = Column(DateTime) + deleted_at = Column(DateTime, nullable=True) deleted = Column(Boolean, nullable=False, default=False) def delete(self, session=None): @@ -97,9 +102,10 @@ class DeckhandBase(models.ModelBase, models.TimestampMixin): class Document(BASE, DeckhandBase): __tablename__ = 'document' __table_args__ = (schema.UniqueConstraint('schema_version', 'kind', - name='uniq_schema_version_kinds0schema_version0kind'),) + name='ix_documents_schema_version_kind'),) - id = Column(String(255), primary_key=True, autoincrement=True) + id = Column(String(36), primary_key=True, + default=lambda: str(uuid.uuid4())) revision_index = Column(Integer, nullable=False) schema_version = Column(String(64), nullable=False) kind = Column(String(64), nullable=False) @@ -108,3 +114,17 @@ class Document(BASE, DeckhandBase): # "metadata" is reserved, so use "doc_metadata" instead. doc_metadata = Column(JSONEncodedDict(), nullable=False) data = Column(JSONEncodedDict(), nullable=False) + + +def register_models(engine): + """Create database tables for all models with the given engine.""" + models = [Document] + for model in models: + model.metadata.create_all(engine) + + +def unregister_models(engine): + """Drop database tables for all models with the given engine.""" + models = [Document] + for model in models: + model.metadata.drop_all(engine) diff --git a/deckhand/objects/documents.py b/deckhand/objects/documents.py index dc2a5096..fbb50516 100644 --- a/deckhand/objects/documents.py +++ b/deckhand/objects/documents.py @@ -19,7 +19,7 @@ from oslo_log import log as logging import oslo_versionedobjects.fields as ovo_fields -from deckhand.db.sqlalchemy import api_models +from deckhand.db.sqlalchemy import api as db_api from deckhand import objects from deckhand.objects import base from deckhand.objects import fields as deckhand_fields @@ -77,19 +77,12 @@ class Document(base.DeckhandPersistentObject, base.DeckhandObject): if not self.document.populated: return - payload = { + values = { 'revision_index': 0, 'schema_version': self.document.schema_version, 'kind': self.document.kind, 'doc_metadata': self.document.metadata, 'data': self.document.data } - db_document = api_models.Document() - db_document.update(payload) - - - # deckhand_context = context.RequestContext() - # try: - # deckhand_context.session.add(db_document) - # except Exception as e: - # LOG.exception(e) + + db_api.document_create(None, values)