No longer import db_api while parsing db __init__.

The db_api field of reddwarf/db/__init__.py was grabbed by importing a
module using utils.import_object. The imported module was always the
sqlalchemy api module, which is nested under the file that imports it,
which caused import errors in multiple contexts. This commit changes
every use of db_api to call a function to load it first, which seems
to fix these problems.

Change-Id: I9515efe02831b521d7f14674e0a2913e476b207d
Fixes: bug #1080706
This commit is contained in:
Tim Simpson 2012-11-19 09:18:55 -06:00
parent f300b17621
commit 9a5d82bf90
11 changed files with 60 additions and 42 deletions

View File

@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version
from reddwarf.common import config
from reddwarf.common import wsgi
from reddwarf.db import db_api
from reddwarf.db import get_db_api
def create_options(parser):
@ -62,7 +62,7 @@ if __name__ == '__main__':
try:
config.Config.load_paste_config('reddwarf', options, args)
conf, app = config.Config.load_paste_app('reddwarf', options, args)
db_api.configure_db(conf)
get_db_api().configure_db(conf)
server = wsgi.Server()
server.start(app, int(options.get('port') or conf['bind_port']),
conf['bind_host'])

View File

@ -40,7 +40,7 @@ from reddwarf import version
from reddwarf.common import config
from reddwarf.common import service
# TODO(hub-cap): find out why the db api isint being imported properly
from reddwarf.db import db_api
from reddwarf.db import get_db_api
if __name__ == '__main__':
@ -61,7 +61,7 @@ if __name__ == '__main__':
# that is injected into the VM
config.Config.append_to_config_values('reddwarf-guestagent',
{'config_file': '/etc/guest_info'}, None)
db_api.configure_db(conf)
get_db_api().configure_db(conf)
server = service.Service.create(binary='reddwarf-guestagent',
host=config.Config.get('guest_id'))
service.serve(server)

View File

@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version
from reddwarf.common import config
from reddwarf.common import utils
from reddwarf.db import db_api
from reddwarf.db import get_db_api
from reddwarf.instance import models as instance_models
@ -57,24 +57,25 @@ def create_options(parser):
class Commands(object):
def __init__(self, conf):
self.db_api = get_db_api()
self.conf = conf
def db_sync(self):
db_api.db_sync(self.conf, repo_path=None)
self.db_api.db_sync(self.conf, repo_path=None)
def db_upgrade(self, version=None, repo_path=None):
db_api.db_upgrade(self.conf, version, repo_path=None)
self.db_api.db_upgrade(self.conf, version, repo_path=None)
def db_downgrade(self, version, repo_path=None):
db_api.db_downgrade(self.conf, version, repo_path=None)
self.db_api.db_downgrade(self.conf, version, repo_path=None)
def execute(self, command_name, *args):
if self.has(command_name):
return getattr(self, command_name)(*args)
def image_update(self, service_name, image_id):
db_api.configure_db(self.conf)
image = db_api.find_by(instance_models.ServiceImage,
self.db_api.configure_db(self.conf)
image = self.db_api.find_by(instance_models.ServiceImage,
service_name=service_name)
if image is None:
# Create a new one
@ -82,13 +83,13 @@ class Commands(object):
image.id = utils.generate_uuid()
image.service_name = service_name
image.image_id = image_id
db_api.save(image)
self.db_api.save(image)
def db_wipe(self, repo_path, service_name, image_id):
"""Drops the database and recreates it."""
from reddwarf.instance import models
from reddwarf.db.sqlalchemy import session
db_api.drop_db(self.conf)
self.db_api.drop_db(self.conf)
self.db_sync()
# Sets up database engine, so the next line will work...
session.configure_db(self.conf)

View File

@ -39,7 +39,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version
from reddwarf.common import config
from reddwarf.common import service
from reddwarf.db import db_api
from reddwarf.db import get_db_api
if __name__ == '__main__':
@ -52,7 +52,7 @@ if __name__ == '__main__':
try:
conf, app = config.Config.load_paste_app('reddwarf-taskmanager',
options, args)
db_api.configure_db(conf)
get_db_api().configure_db(conf)
server = service.Service.create(binary='reddwarf-taskmanager',
manager='reddwarf.taskmanager.manager.TaskManager',

View File

@ -36,7 +36,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version
from reddwarf.common import config
from reddwarf.common import wsgi
from reddwarf.db import db_api
from reddwarf.db import get_db_api
def create_options(parser):
@ -75,7 +75,7 @@ if __name__ == '__main__':
(options, args) = config.parse_options(oparser)
config.Config.load_paste_config('reddwarf', options, args)
conf, app = config.Config.load_paste_app('reddwarf', options, args)
db_api.configure_db(conf)
get_db_api().configure_db(conf)
port = int(options.get('port') or conf['bind_port'])
if options['fork']:
pid = os.fork()

View File

@ -39,7 +39,7 @@ if os.path.exists(os.path.join(possible_topdir, 'reddwarf', '__init__.py')):
from reddwarf import version
from reddwarf.common import config
from reddwarf.common import service
from reddwarf.db import db_api
from reddwarf.db import get_db_api
if __name__ == '__main__':
@ -52,7 +52,7 @@ if __name__ == '__main__':
try:
conf, app = config.Config.load_paste_app('reddwarf-taskmanager',
options, args)
db_api.configure_db(conf)
get_db_api().configure_db(conf)
server = service.Service.create(binary='reddwarf-taskmanager')
service.serve(server)
service.wait()

View File

@ -21,9 +21,12 @@ from reddwarf.common import utils
from reddwarf.common import config
db_api = utils.import_object(
config.Config.get("db_api_implementation",
"reddwarf.db.sqlalchemy.api"))
db_api_opt = config.Config.get("db_api_implementation",
"reddwarf.db.sqlalchemy.api")
def get_db_api():
return utils.import_object(db_api_opt)
class Query(object):
@ -38,25 +41,29 @@ class Query(object):
self._query_func = query_func
self._model = model
self._conditions = conditions
self.db_api = get_db_api()
def all(self):
return db_api.list(self._query_func, self._model, **self._conditions)
return self.db_api.list(self._query_func, self._model,
**self._conditions)
def count(self):
return db_api.count(self._query_func, self._model, **self._conditions)
return self.db_api.count(self._query_func, self._model,
**self._conditions)
def __iter__(self):
return iter(self.all())
def update(self, **values):
db_api.update_all(self._query_func, self._model, self._conditions,
values)
self.db_api.update_all(self._query_func, self._model, self._conditions,
values)
def delete(self):
db_api.delete_all(self._query_func, self._model, **self._conditions)
self.db_api.delete_all(self._query_func, self._model,
**self._conditions)
def limit(self, limit=200, marker=None, marker_column=None):
return db_api.find_all_by_limit(
return self.db_api.find_all_by_limit(
self._query_func,
self._model,
self._conditions,
@ -75,7 +82,7 @@ class Queryable(object):
def __getattr__(self, item):
return lambda model, **conditions: Query(
model, query_func=getattr(db_api, item), **conditions)
model, query_func=getattr(get_db_api(), item), **conditions)
db_query = Queryable()

View File

@ -14,7 +14,8 @@
import logging
from reddwarf import db
from reddwarf.db import get_db_api
from reddwarf.db import db_query
from reddwarf.common import exception
from reddwarf.common import models
from reddwarf.common import pagination
@ -36,19 +37,23 @@ class DatabaseModelBase(models.ModelBase):
raise exception.InvalidModelError(errors=instance.errors)
return instance
@property
def db_api(self):
return get_db_api()
def save(self):
if not self.is_valid():
raise exception.InvalidModelError(errors=self.errors)
self['updated'] = utils.utcnow()
LOG.debug(_("Saving %s: %s") %
(self.__class__.__name__, self.__dict__))
return db.db_api.save(self)
return self.db_api.save(self)
def delete(self):
self['updated'] = utils.utcnow()
LOG.debug(_("Deleting %s: %s") %
(self.__class__.__name__, self.__dict__))
return db.db_api.delete(self)
return self.db_api.delete(self)
def __init__(self, **kwargs):
self.merge_attributes(kwargs)
@ -70,11 +75,11 @@ class DatabaseModelBase(models.ModelBase):
@classmethod
def get_by(cls, **kwargs):
return db.db_api.find_by(cls, **cls._process_conditions(kwargs))
return get_db_api().find_by(cls, **cls._process_conditions(kwargs))
@classmethod
def find_all(cls, **kwargs):
return db.db_query.find_all(cls, **cls._process_conditions(kwargs))
return db_query.find_all(cls, **cls._process_conditions(kwargs))
@classmethod
def _process_conditions(cls, raw_conditions):

View File

@ -21,11 +21,10 @@ Model classes that extend the instances functionality for MySQL instances.
import logging
from reddwarf import db
from reddwarf.common import config
from reddwarf.common import exception
from reddwarf.common import utils
from reddwarf.db import get_db_api
from reddwarf.instance import models as base_models
from reddwarf.guestagent.db import models as guest_models
from reddwarf.common.remote import create_guest_client
@ -121,11 +120,11 @@ class RootHistory(object):
def save(self):
LOG.debug(_("Saving %s: %s") % (self.__class__.__name__,
self.__dict__))
return db.db_api.save(self)
return get_db_api().save(self)
@classmethod
def load(cls, context, instance_id):
history = db.db_api.find_by(cls, id=instance_id)
history = get_db_api().find_by(cls, id=instance_id)
return history
@classmethod

View File

@ -151,7 +151,8 @@ def import_class(import_str):
__import__(mod_str)
return getattr(sys.modules[mod_str], class_str)
except (ImportError, ValueError, AttributeError):
raise exception.NotFound('Class %s cannot be found' % class_str)
raise exception.NotFound('Class from %s import %s cannot be found'
% (mod_str, class_str))
def import_object(import_str):
@ -159,8 +160,11 @@ def import_object(import_str):
try:
__import__(import_str)
return sys.modules[import_str]
except ImportError:
return import_class(import_str)
except ImportError as ie:
try:
return import_class(import_str)
except exception.NotFound:
raise ie
def isotime(at=None):

View File

@ -30,11 +30,12 @@ def add_support_for_localization():
def initialize_reddwarf(config_file):
# The test version of poll_until doesn't utilize LoopingCall.
import optparse
from reddwarf.db import db_api
from reddwarf.db import get_db_api
from reddwarf.common import config as rd_config
from reddwarf.common import wsgi
from reddwarf import version
db_api = get_db_api()
def create_options(parser):
parser.add_option('-p', '--port', dest="port", metavar="PORT",
@ -62,9 +63,10 @@ def initialize_reddwarf(config_file):
def initialize_database(rd_conf):
from reddwarf.db import db_api
from reddwarf.db import get_db_api
from reddwarf.instance import models
from reddwarf.db.sqlalchemy import session
db_api = get_db_api()
db_api.drop_db(rd_conf) # Destroys the database, if it exists.
db_api.db_sync(rd_conf)
session.configure_db(rd_conf)