def _import_models(self): old_models = get_all_models() import_all_models(self.package_name) added_models = get_all_models() - old_models # Ensure that only plugin schemas have been touched. It would be nice if we could actually # restrict a plugin to plugin_PLUGNNAME but since we load all models from the plugin's package # which could contain more than one plugin this is not easily possible. for model in added_models: schema = model.__table__.schema # Allow models with non-plugin schema if they specify `polymorphic_identity` without a dedicated table if ('polymorphic_identity' in getattr(model, '__mapper_args__', ()) and '__tablename__' not in model.__dict__): continue if not schema.startswith('plugin_'): raise Exception("Plugin '{}' added a model which is not in a plugin schema ('{}' in '{}')" .format(self.name, model.__name__, schema))
def _make_shell_context(): context = {} info = [cformat('%{white!}Available objects')] add_to_context = partial(_add_to_context, context, info) add_to_context_multi = partial(_add_to_context_multi, context, info) add_to_context_smart = partial(_add_to_context_smart, context, info) # Common stdlib modules info.append(cformat('*** %{magenta!}stdlib%{reset} ***')) DATETIME_ATTRS = ('date', 'time', 'datetime', 'timedelta') ORM_ATTRS = ('joinedload', 'defaultload', 'contains_eager', 'lazyload', 'noload', 'subqueryload', 'undefer', 'undefer_group', 'load_only') add_to_context_multi([getattr(datetime, attr) for attr in DATETIME_ATTRS] + [getattr(sqlalchemy.orm, attr) for attr in ORM_ATTRS] + [itertools, re, sys, os], color='yellow') # Models info.append(cformat('*** %{magenta!}Models%{reset} ***')) models = [ cls for cls in sorted(get_all_models(), key=attrgetter('__name__')) if hasattr(cls, '__table__') ] add_to_context_smart(models) # Tasks info.append(cformat('*** %{magenta!}Tasks%{reset} ***')) tasks = [ task for task in sorted(celery.tasks.values(), key=attrgetter('name')) if not task.name.startswith('celery.') ] add_to_context_smart(tasks, get_name=lambda x: x.name.replace('.', '_'), color='blue!') # Plugins plugins = [ type(plugin) for plugin in sorted(list(plugin_engine.get_active_plugins().values()), key=attrgetter('name')) ] if plugins: info.append(cformat('*** %{magenta!}Plugins%{reset} ***')) add_to_context_multi(plugins, color='yellow!') # Utils info.append(cformat('*** %{magenta!}Misc%{reset} ***')) add_to_context(celery, 'celery', doc='celery app', color='blue!') add_to_context(db, 'db', doc='sqlalchemy db interface', color='cyan!') add_to_context(now_utc, 'now_utc', doc='get current utc time', color='cyan!') add_to_context(config, 'config', doc='indico config') add_to_context(current_app, 'app', doc='flask app') add_to_context(lambda *a, **kw: server_to_utc(datetime.datetime(*a, **kw)), 'dt', doc='like datetime() but converted from localtime to utc') add_to_context(Event.get, 'E', doc='get event by id') # Stuff from plugins signals.plugin.shell_context.send( add_to_context=add_to_context, add_to_context_multi=add_to_context_multi) return context, info
def _mappers_configured(): # We need to create the column property here since we cannot import # Attachment/AttachmentFolder while the models are being defined for model in get_all_models(): if hasattr(model, '__table__') and issubclass(model, AttachedItemsMixin): _make_attachment_count_column_property(model)
def _make_globals(**extra): """ Build a globals dict for the exec/eval environment that contains all the models and whatever extra data is needed. """ globals_ = {cls.__name__: cls for cls in get_all_models() if hasattr(cls, '__table__')} globals_.update(extra) return globals_
def _find_backrefs(): backrefs = defaultdict(list) for cls in get_all_models(): if not hasattr(cls, '__table__'): continue mapper = inspect(cls) for rel in mapper.relationships: if rel.backref is None: continue backref_name = rel.backref if isinstance(rel.backref, str) else rel.backref[0] if cls != rel.class_attribute.class_: # skip relationships defined on a parent class continue backrefs[rel.mapper.class_].append((backref_name, cls.__name__, rel.key)) return backrefs