예제 #1
0
 def setup_model():
     from sqlalchemy.orm import configure_mappers
     from camelot.core.sql import metadata
     metadata.bind = settings.ENGINE()
     #
     # import all the needed model files to make sure the mappers and tables
     # are defined before creating them in the database
     #
     from camelot.model import (party, authentication, i18n, fixture,
                                memento, batch_job)
     from . import model
     logger.debug('loaded datamodel for %s'%party.__name__)
     logger.debug('loaded datamodel for %s'%authentication.__name__)
     logger.debug('loaded datamodel for %s'%i18n.__name__)
     logger.debug('loaded datamodel for %s'%fixture.__name__)
     logger.debug('loaded datamodel for %s'%memento.__name__)
     logger.debug('loaded datamodel for %s'%batch_job.__name__)
     logger.debug('loaded datamodel for %s'%model.__name__)
     #
     # create the tables for all models, configure mappers first, to make
     # sure all deferred properties have been handled, as those could
     # create tables or columns
     #
     configure_mappers()
     metadata.create_all()
     # 
     # Load sample data with the fixure mechanism
     #
     from camelot_example.fixtures import load_movie_fixtures
     load_movie_fixtures()
     #
     # setup the views
     #
     from camelot_example.view import setup_views
     setup_views()
예제 #2
0
 def setup_model():
     from sqlalchemy.orm import configure_mappers
     from camelot.core.sql import metadata
     metadata.bind = settings.ENGINE()
     import camelot.model.party
     import camelot.model.authentication
     import camelot.model.i18n
     import camelot.model.fixture
     import camelot.model.memento
     import camelot.model.batch_job
     import camelot_example.model
     #
     # create the tables for all models, configure mappers first, to make
     # sure all deferred properties have been handled, as those could
     # create tables or columns
     #
     configure_mappers()
     metadata.create_all()
     from camelot.model.authentication import update_last_login
     #update_last_login()
     # 
     # Load sample data with the fixure mechanism
     #
     from camelot_example.fixtures import load_movie_fixtures
     load_movie_fixtures()
     #
     # setup the views
     #
     from camelot_example.view import setup_views
     setup_views()
예제 #3
0
 def start_model_thread(self):
     """Launch the second thread where the model lives"""
     from camelot.view.model_thread import get_model_thread, construct_model_thread
     from camelot.view.remote_signals import construct_signal_handler
     from camelot.core.conf import settings
     from camelot.core.sql import metadata
     metadata.bind = settings.ENGINE()
     construct_model_thread()
     construct_signal_handler()
     mt = get_model_thread()
     mt.setup_exception_signal.connect( self.initialization_exception )
     mt.start()
예제 #4
0
def update_database_from_model():
    """Introspection the model and add missing columns in the database.    
    this function can be ran in setup_model after::
    
        metadata.create_all()
        
    """
    migrate_engine = settings.ENGINE()
    migrate_connection = migrate_engine.connect()

    from sqlalchemy.schema import MetaData
    from migrate.versioning import schemadiff
    from migrate.changeset import create_column
    schema_diff = schemadiff.SchemaDiff(
        metadata, MetaData(migrate_connection, reflect=True))

    for table_name, difference in schema_diff.tables_different.items():
        for column in difference.columns_missing_from_B:
            LOGGER.warn('column %s missing in table %s' % (column, table_name))
            table = metadata.tables[table_name]
            create_column(column, table)
예제 #5
0
 def setUp(self):
     super(ExampleModelCase, self).setUp()
     from camelot.model import (authentication, batch_job, fixture, party,
                                i18n, memento)
     metadata.bind = settings.ENGINE()
     metadata.create_all()
예제 #6
0
    def restore(self):
        """Generator function that yields tuples :
        (numer_of_steps_completed, total_number_of_steps, description_of_current_step)
        while performing a restore.
        """
        #
        # The restored database may contain different AuthenticationMechanisms
        #
        from camelot.model.authentication import clear_current_authentication
        clear_current_authentication()
        #
        # Proceed with the restore
        #
        import os
        from camelot.core.files.storage import StoredFile
        from sqlalchemy import create_engine
        from sqlalchemy import MetaData
        from sqlalchemy.pool import NullPool

        yield (0, 0, _('Open backup file'))
        if self._storage:
            if not self._storage.exists(self._filename):
                raise Exception('Backup file does not exist')
            stored_file = StoredFile(self._storage, self._filename)
            filename = self._storage.checkout(stored_file)
        else:
            if not os.path.exists(self._filename):
                raise Exception('Backup file does not exist')
            filename = self._filename
        from_engine = create_engine('sqlite:///%s' % filename,
                                    poolclass=NullPool)

        yield (0, 0, _('Prepare database for restore'))
        to_engine = settings.ENGINE()
        self.prepare_schema_for_restore(from_engine, to_engine)

        yield (0, 0, _('Analyzing backup structure'))
        from_meta_data = MetaData()
        from_meta_data.bind = from_engine
        from_meta_data.reflect()

        yield (0, 0, _('Analyzing database structure'))
        to_meta_data = MetaData()
        to_meta_data.bind = to_engine
        to_meta_data.reflect()
        to_tables = list(table for table in to_meta_data.sorted_tables
                         if self.restore_table_filter(table))
        number_of_tables = len(to_tables)
        steps = number_of_tables * 2 + 2

        for i, to_table in enumerate(reversed(to_tables)):
            yield (i, steps, _('Delete data from table %s') % to_table.name)
            self.delete_table_data(to_table)

        for i, to_table in enumerate(to_tables):
            if to_table.name in from_meta_data.tables:
                yield (number_of_tables + i, steps,
                       _('Copy data from table %s') % to_table.name)
                self.copy_table_data(from_meta_data.tables[to_table.name],
                                     to_table)

        yield (number_of_tables * 2 + 1, steps,
               _('Update schema after restore'))
        self.update_schema_after_restore(from_engine, to_engine)

        from_engine.dispose()
        to_engine.dispose()

        yield (number_of_tables * 2 + 2, steps, _('Load new data'))
        from sqlalchemy.orm.session import _sessions
        for session in _sessions.values():
            session.expunge_all()

        yield (1, 1, _('Restore completed'))
예제 #7
0
    def backup(self):
        """Generator function that yields tuples :
        (numer_of_steps_completed, total_number_of_steps, description_of_current_step)
        while performing a backup.
        """
        import os
        import tempfile
        import shutil
        from sqlalchemy import create_engine, types
        from sqlalchemy import MetaData, Table, Column
        from sqlalchemy.pool import NullPool

        yield (0, 0, _('Analyzing database structure'))
        from_engine = settings.ENGINE()
        from_meta_data = MetaData()
        from_meta_data.bind = from_engine
        from_meta_data.reflect()

        yield (0, 0, _('Preparing backup file'))
        #
        # We'll first store the backup in a temporary file, since
        # the selected file might be on a server or in a storage
        #
        file_descriptor, temp_file_name = tempfile.mkstemp(suffix='.db')
        os.close(file_descriptor)
        logger.info("preparing backup to '%s'" % temp_file_name)
        if os.path.exists(self._filename):
            os.remove(self._filename)
        to_engine = create_engine(u'sqlite:///%s' % temp_file_name,
                                  poolclass=NullPool)
        to_meta_data = MetaData()
        to_meta_data.bind = to_engine
        #
        # Only copy tables, to prevent issues with indices and constraints
        #
        from_and_to_tables = []
        for from_table in from_meta_data.sorted_tables:
            if self.backup_table_filter(from_table):
                new_cols = []
                for col in from_table.columns:
                    new_type = self.get_backup_column_type(col.type)
                    if not isinstance(new_type, types.NullType):
                        new_cols.append(Column(col.name, new_type))
                    else:
                        logger.warn('cannot backup column %s of table %s' %
                                    (col.name, from_table.name))
                to_table = Table(from_table.name, to_meta_data, *new_cols)
                to_table.create(to_engine)
                from_and_to_tables.append((from_table, to_table))

        number_of_tables = len(from_and_to_tables)
        for i, (from_table, to_table) in enumerate(from_and_to_tables):
            yield (i, number_of_tables + 1,
                   _('Copy data of table %s') % from_table.name)
            self.copy_table_data(from_table, to_table)
        yield (number_of_tables, number_of_tables + 1,
               _('Store backup at requested location'))
        from_engine.dispose()
        to_engine.dispose()
        if not self._storage:
            logger.info(u'move backup file to its final location')
            shutil.move(temp_file_name, self._filename)
        else:
            logger.info(u'check backfup file in to storage with name %s' %
                        self._filename)
            self._storage.checkin(temp_file_name, self._filename)
            os.remove(temp_file_name)
        yield (number_of_tables + 1, number_of_tables + 1,
               _('Backup completed'))
예제 #8
0
 def test_simple_settings(self):
     from camelot.core.conf import SimpleSettings
     settings = SimpleSettings('Conceptive Engineering', 'Camelot Test')
     self.assertTrue(settings.ENGINE())
     self.assertTrue(settings.CAMELOT_MEDIA_ROOT())