[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