[openstack-dev] [Solum] Some initial code copying for db/migration

Clayton Coleman ccoleman at redhat.com
Fri Nov 15 05:05:46 UTC 2013


With no feedback on remotability so far (we can touch base at F2F next week) here's a representative sample of the object model with sqlalchemy implementations approach, without some of the bits that would enable remotability (primarily the ability to rehydrate an object with the correct sqlalchemy metadata). [1]

  [1] https://github.com/smarterclayton/solum/commit/d9d83aac0fc98663f1daa9914edeb52faf0cc37d

Highlights:

  Imported nova object code, made the following changes to solum/objects/base.py:

  * Used DomainObject instead of Object, also suggested were OsloObject or 
    OSObject.  I like DomainObject but I like Fowler, what can I say...

  * DomainObject has the metaclass, but is a subclass of AbstractDomainObject 
    which contains all of the core mixin logic.  Allows subclasses that have
    their own metaclasses to avoid having to do metaclass hijinks by using
    AbstractDomainObject and objects.base.register_obj_class

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/base.py#L344

  * Moved the _obj_classes registry magic out of ObjectMetaClass and into 
    its own method for easier use.  Since this is a subclass based implementation,
    having a separate method feels more appropriate for a factory/registry
    pattern.

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/base.py#L103

  * Takes a dependency on rpc serializer, debating whether this was
    good or bad (not everyone using objects needs rpc?)


  solum/objects/__init__.py

  * solum.objects.load() allows the framework to load a configured set of 
    implementation subclasses that can change. Nova doesn't have
    subclasses of their objects yet so this seemed like the simplest possible
    change, without introducing a new magic factory.  Called by 
    prepare_service() when API is started up, after config is parsed.

  * Also provides solum.objects.registry.Application which abstracts knowing 
    about the implementation subclass in play

  * solum.objects.new_schema() and transition_schema() are global helpers
    for determining whether you should be reading newly introduce/changed 
    fields from the schema, or whether you should only be writing them.
    I plan to have a better example in test tomorrow.

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/__init__.py


  Application object interface (fields, docs, version) in solum/objects/application.py


  Specific sqlalchemy implementation solum/objects/sqlalchemy/__init__.py

  * As simple as I could make it - simply calls register_obj_class in its
    load()

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/sqlalchemy/__init__.py


  Common SQLAlchemy code in solum/objects/sqlalchemy/models.py

  * SolumBase mixin abstracts all the common CRUD that would be part of the 
    base solum/objects/application.py interfaces.  Subclasses (actual model
    objects) would override as necessary.

  * Abstracts save() logic that must set new schema transition elements (copy
    fields when transitioning)

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/sqlalchemy/models.py#L89

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/sqlalchemy/models.py

  
  Application implementation in solum/objects/sqlalchemy/application.py

  * I don't have examples of transition schema, but you could use an if statement 
    in the class initializer:

      id = Column(Integer, primary_key=True)
      if objects.new_schema():
          name = Column(String, nullable=True)

    This would allow you to also set sqlalchemy synonym calls when renaming columns
    for each version of the schema.  Would like to make it more testable, but if 
    you assume a restart between each old -> transitioning -> new the static
    initialization could be associated with a schema check call in load() that blocks
    service initialization if the incorrect mode or schema is present.

    https://github.com/smarterclayton/solum/blob/d9d83aac0fc98663f1daa9914edeb52faf0cc37d/solum/objects/sqlalchemy/application.py


The rest of the code needs to be rebased against russell's import changeset, and dbsync isn't necessary (needs to be replaced with alembic when we hit that point).



More information about the OpenStack-dev mailing list