def model_run(self, model_context): from camelot.view.action_steps import (SelectFile, UpdateProgress, Refresh, FlushSession) select_files = SelectFile('Txt Files (*.txt *.csv);;All Files (*)') select_files.single = False file_names = yield select_files file_count = len(file_names) import os from camelot.core.orm import Session from rms.Model.Orar import Orar session = Session() for i, file_name in enumerate(file_names): yield UpdateProgress(i, file_count) title = os.path.splitext(os.path.basename(file_name))[0] print(file_name) for line in open(file_name): vals = line.split(';')[:-1] if len(vals) != 8: raise ImportException("Fisierul nu e dat bine") if vals[2] not in ['0', '1', '2']: raise ImportException("Frecventa nu e data bine") print(vals) orar = Orar(*vals) print(orar) session.add(orar) yield FlushSession(session) # begin refresh yield Refresh()
def test_i18n( self ): from camelot.model.i18n import Translation, ExportAsPO session = Session() session.execute( Translation.__table__.delete() ) self.assertEqual( Translation.translate( 'bucket', 'nl_BE' ), None ) # run twice to check all branches in the code Translation.translate_or_register( 'bucket', 'nl_BE' ) Translation.translate_or_register( 'bucket', 'nl_BE' ) self.assertEqual( Translation.translate( 'bucket', 'nl_BE' ), 'bucket' ) self.assertEqual( Translation.translate( '', 'nl_BE' ), '' ) self.assertEqual( Translation.translate_or_register( '', 'nl_BE' ), '' ) # clear the cache Translation._cache.clear() # fill the cache again translation = Translation( language = 'nl_BE', source = 'bucket', value = 'emmer', uid=1 ) orm.object_session( translation ).flush() self.assertEqual( Translation.translate( 'bucket', 'nl_BE' ), 'emmer' ) export_action = ExportAsPO() model_context = MockModelContext() model_context.obj = translation try: generator = export_action.model_run( model_context ) file_step = generator.next() generator.send( ['/tmp/test.po'] ) except StopIteration: pass
def test_i18n(self): from camelot.model.i18n import Translation, ExportAsPO session = Session() session.execute(Translation.__table__.delete()) self.assertEqual(Translation.translate('bucket', 'nl_BE'), None) # run twice to check all branches in the code Translation.translate_or_register('bucket', 'nl_BE') Translation.translate_or_register('bucket', 'nl_BE') self.assertEqual(Translation.translate('bucket', 'nl_BE'), 'bucket') self.assertEqual(Translation.translate('', 'nl_BE'), '') self.assertEqual(Translation.translate_or_register('', 'nl_BE'), '') # clear the cache Translation._cache.clear() # fill the cache again translation = Translation(language='nl_BE', source='bucket', value='emmer', uid=1) orm.object_session(translation).flush() self.assertEqual(Translation.translate('bucket', 'nl_BE'), 'emmer') export_action = ExportAsPO() model_context = MockModelContext() model_context.obj = translation try: generator = export_action.model_run(model_context) file_step = generator.next() generator.send(['/tmp/test.po']) except StopIteration: pass
def setUp( self ): super( CollectionProxyCase, self ).setUp() session = Session() self.collection = list( session.query( Person ).all() ) self.proxy = CollectionProxy( self.person_admin, collection_getter=lambda:self.collection, columns_getter=self.person_admin.get_columns )
def test_refresh( self ): from camelot.core.orm import Session from camelot.model.party import Person refresh_action = application_action.Refresh() session = Session() session.expunge_all() # create objects in various states # p1 = Person(first_name = u'p1', last_name = u'persistent' ) p2 = Person(first_name = u'p2', last_name = u'dirty' ) p3 = Person(first_name = u'p3', last_name = u'deleted' ) p4 = Person(first_name = u'p4', last_name = u'to be deleted' ) p5 = Person(first_name = u'p5', last_name = u'detached' ) p6 = Person(first_name = u'p6', last_name = u'deleted outside session' ) session.flush() p3.delete() session.flush() p4.delete() p2.last_name = u'clean' # # delete p6 without the session being aware # person_table = Person.table session.execute( person_table.delete().where( person_table.c.party_id == p6.id ) ) # # refresh the session through the action # list( refresh_action.model_run( self.context ) ) self.assertEqual( p2.last_name, u'dirty' )
def setUp(self): super(CollectionProxyCase, self).setUp() session = Session() self.collection = list(session.query(Person).all()) self.proxy = CollectionProxy( self.person_admin, collection_getter=lambda: self.collection, columns_getter=self.person_admin.get_columns)
def setUp(self): super(PartyCase, self).setUp() from camelot.admin.application_admin import ApplicationAdmin self.session = Session() self.app_admin = ApplicationAdmin() self.person_admin = self.app_admin.get_related_admin(party.Person) self.organization_admin = self.app_admin.get_related_admin( party.Organization)
class SearchCase( unittest.TestCase ): """Test the creation of search queries""" def setUp( self ): metadata.bind = settings.ENGINE() metadata.create_all() self.session = Session() # # insert the value of i in each column of T, that can be searched for # for (i,name), definition in types_to_test.items(): value = self.value_for_type( definition, i ) t = T() setattr( t, name, value ) self.session.flush() self.admin = TAdmin() def value_for_type( self, definition, i ): value = i if issubclass( definition, sqlalchemy.types.DateTime ): value = datetime.datetime( year = 2000, month = 1, day = 1, hour = 1, minute = i ) elif issubclass( definition, sqlalchemy.types.Date ): value = datetime.date( year = 2000, month = 1, day = i%31 ) elif issubclass( definition, sqlalchemy.types.Time ): value = datetime.time( hour = 1, minute = i ) elif issubclass( definition, sqlalchemy.types.String ): value = str( i ) elif issubclass( definition, sqlalchemy.types.Boolean ): value = True return value def test_search_decorator( self ): """Verify it search works for most common types""" from camelot.view.search import create_entity_search_query_decorator for (i,name), definition in types_to_test.items(): value = self.value_for_type( definition, i ) # # @todo : search for types that need special conversion to string # is skipped for now because the test would become too # convoluted, this should work through a to_string field # attribute. # if isinstance( value, ( datetime.date, datetime.time, bool) ): continue string_value = str( value ) search_decorator = create_entity_search_query_decorator( self.admin, string_value ) query = self.session.query( T ) query = search_decorator( query ) #print query self.assertTrue( query.count() > 0 )
def set_current_version( cls, fixture_class = None, fixture_version = 0 ): """Set the current version of the fixtures in the database for a certain fixture class. :param fixture_class: the fixture class for which to get the version :param fixture_version: the version number to which to set the fixture version """ from sqlalchemy.orm.session import Session obj = Session().query( cls ).filter_by( fixture_class = fixture_class ).first() if not obj: obj = FixtureVersion( fixture_class = fixture_class ) obj.fixture_version = fixture_version Session.object_session( obj ).flush()
def test_fixture(self): from camelot.model.party import Person from camelot.model.fixture import Fixture session = Session() self.assertEqual(Fixture.find_fixture_key(Person, -1), None) p1 = Person() self.assertEqual(Fixture.find_fixture_key_and_class(p1), (None, None)) session.expunge(p1) # insert a new Fixture p2 = Fixture.insert_or_update_fixture(Person, 'test', { 'first_name': 'Peter', 'last_name': 'Principle' }, fixture_class='test') # see if we can find it back self.assertEqual(Fixture.find_fixture_key(Person, p2.id), 'test') self.assertEqual(Fixture.find_fixture_key_and_class(p2), ('test', 'test')) self.assertEqual( Fixture.find_fixture_keys_and_classes(Person)[p2.id], ('test', 'test')) # delete the person, and insert it back in the same fixture session.delete(p2) session.flush() p3 = Fixture.insert_or_update_fixture(Person, 'test', { 'first_name': 'Peter', 'last_name': 'Principle' }, fixture_class='test') self.assertNotEqual(p2, p3) # remove all fixtures Fixture.remove_all_fixtures(Person)
def get_current_version(cls, fixture_class=None, session=None): """Get the current version of the fixtures in the database for a certain fixture class. :param fixture_class: the fixture class for which to get the version :param session: the session to use to query the database, if `None` is given, the default Camelot session is used :return: an integer representing the current version, 0 if no version found """ if session is None: session = Session() obj = session.query(cls).filter_by(fixture_class=fixture_class).first() if obj: return obj.fixture_version return 0
def setUp(self): super( PartyCase, self ).setUp() from camelot.admin.application_admin import ApplicationAdmin self.session = Session() self.app_admin = ApplicationAdmin() self.person_admin = self.app_admin.get_related_admin( party.Person ) self.organization_admin = self.app_admin.get_related_admin( party.Organization )
def translate(cls, source, language): """Translate source to language, return None if no translation is found""" if source: key = (source, language) if key in cls._cache: return cls._cache[key] query = Session().query(cls) query = query.filter( sql.and_(cls.source == unicode(source), cls.language == language, cls.uid != 0)) translation = query.first() if translation: cls._cache[key] = translation.value return translation.value return None return ''
def register_changes( self, memento_changes ): """Create rows in the memento table :param memento_changes: an iterator over `memento_change` tuples that need to be stored in the memento table. """ from camelot.core.orm import Session from camelot.model.memento import Memento authentication_id = self._get_authentication_id() connection = Session().connection(mapper=orm.class_mapper( Memento )) session = orm.Session(bind=connection, autocommit=True) mementos = [] for m in memento_changes: if len( m.primary_key ) == 1: mementos.append( Memento( model=m.model, primary_key=m.primary_key[0], previous_attributes=m.previous_attributes, memento_type=self.memento_id_by_type.get(m.memento_type, None), authentication_id=authentication_id, _session=session ) ) if len( mementos ): try: session.flush() except exc.DatabaseError as e: LOGGER.error( 'Programming Error, could not flush history', exc_info = e )
def test_query(self): # # The query attribute of a class should return a query bound to # the session belonging to the current thread # from PyQt4 import QtCore class A(self.Entity): name = Field(String(32)) self.create_all() with self.session.begin(): a1 = A(name="a1") self.assertEqual(A.query.count(), 1) session_1 = A.query.session self.assertEqual(session_1, Session()) class QueryThread(QtCore.QThread): def run(self): self.query_session_2 = A.query.session self.orm_session_2 = Session() thread = QueryThread() thread.start() thread.wait() self.assertNotEqual(session_1, thread.orm_session_2) self.assertNotEqual(session_1, thread.query_session_2)
def flush(self, entity_instance): """Flush the pending changes of this entity instance to the backend""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) if session: objects_to_flush = set([entity_instance]) self._expand_compounding_objects( objects_to_flush ) # # Create a list of changes # changes = [] for obj_to_flush in objects_to_flush: if obj_to_flush in session.dirty: modifications = {} try: modifications = self.get_modifications( obj_to_flush ) except Exception, e: # todo : there seems to be a bug in sqlalchemy that causes the # get history to fail in some cases logger.error( 'could not get modifications from object', exc_info = e ) primary_key = self.primary_key( obj_to_flush ) if modifications and (None not in primary_key): change = memento_change( model = unicode( self.entity.__name__ ), memento_type = 'before_update', primary_key = primary_key, previous_attributes = modifications ) changes.append( change ) session.flush( objects_to_flush ) # # If needed, track the changes # memento = self.get_memento() if changes and memento != None: memento.register_changes( changes )
def translate( cls, source, language ): """Translate source to language, return None if no translation is found""" if source: key = ( source, language ) if key in cls._cache: return cls._cache[key] query = Session().query( cls ) query = query.filter( sql.and_( cls.source == unicode( source ), cls.language == language, cls.uid != 0 ) ) translation = query.first() if translation: cls._cache[key] = translation.value return translation.value return None return ''
def flush(self, entity_instance): """Flush the pending changes of this entity instance to the backend""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) if session: modifications = {} try: modifications = self.get_modifications( entity_instance ) except Exception, e: # todo : there seems to be a bug in sqlalchemy that causes the # get history to fail in some cases logger.error( 'could not get modifications from object', exc_info = e ) session.flush( [entity_instance] ) # # If needed, track the changes # primary_key = self.primary_key( entity_instance ) if modifications and (None not in primary_key): memento = self.get_memento() if memento != None: change = memento_change( model = unicode( self.entity.__name__ ), memento_type = 'before_update', primary_key = primary_key, previous_attributes = modifications ) memento.register_changes( [change] )
def delete(self, entity_instance): """Delete an entity instance""" session = Session.object_session(entity_instance) # # new and deleted instances cannot be deleted # if session: if entity_instance in session.new: session.expunge(entity_instance) elif entity_instance not in session.deleted: # # only if we know the primary key, we can keep track of its history # primary_key = self.primary_key(entity_instance) if not None in primary_key: # save the state before the update memento = self.get_memento() if memento != None: modifications = entity_to_dict(entity_instance) change = memento_change( model=six.text_type(self.entity.__name__), memento_type='before_delete', primary_key=primary_key, previous_attributes=modifications) memento.register_changes([change]) session.delete(entity_instance) session.flush()
def delete(self, entity_instance): """Delete an entity instance""" session = Session.object_session( entity_instance ) # # new and deleted instances cannot be deleted # if session: if entity_instance in session.new: session.expunge(entity_instance) elif entity_instance not in session.deleted: # # only if we know the primary key, we can keep track of its history # primary_key = self.primary_key( entity_instance ) if not None in primary_key: # save the state before the update memento = self.get_memento() if memento != None: modifications = entity_to_dict( entity_instance ) change = memento_change( model = unicode( self.entity.__name__ ), memento_type = 'before_delete', primary_key = primary_key, previous_attributes = modifications ) memento.register_changes( [change] ) session.delete( entity_instance ) self.flush( entity_instance )
def flush(self, entity_instance): """Flush the pending changes of this entity instance to the backend""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) if session: modifications = {} try: modifications = self.get_modifications( entity_instance ) except Exception, e: # todo : there seems to be a bug in sqlalchemy that causes the # get history to fail in some cases logger.error( 'could not get modifications from object', exc_info = e ) session.flush( [entity_instance] ) # # If needed, track the changes # primary_key = self.primary_key( entity_instance ) if modifications and (primary_key != None) and len(primary_key)==1: from camelot.model.memento import Memento # only register the update when the camelot model is active if hasattr(Memento, 'query'): from camelot.model.authentication import get_current_authentication history = Memento( model = unicode( self.entity.__name__ ), memento_type = 'before_update', primary_key = primary_key[0], previous_attributes = modifications, authentication = get_current_authentication() ) try: history.flush() except exc.DatabaseError, e: self.logger.error( 'Programming Error, could not flush history', exc_info = e )
def add( self, obj ): """Adds the entity instance to the default session, if it is not yet attached to a session""" import elixir session = Session.object_session( obj ) if session == None: elixir.session.add( obj )
def delete(self, entity_instance): """Delete an entity instance""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) # # new and deleted instances cannot be deleted # if session: if entity_instance in session.new: session.expunge(entity_instance) elif (entity_instance not in session.deleted) and \ (entity_instance in session): # if the object is not in the session, it might already be deleted # # only if we know the primary key, we can keep track of its history # primary_key = self.primary_key( entity_instance ) if not None in primary_key: # save the state before the update memento = self.get_memento() if memento != None: modifications = dict() change = memento_change( model = unicode( self.entity.__name__ ), memento_type = 'before_delete', primary_key = primary_key, previous_attributes = modifications ) memento.register_changes( [change] ) session.delete( entity_instance ) session.flush( [entity_instance] )
def model_run( self, model_context ): from camelot.view.action_steps import ( SelectFile, UpdateProgress, Refresh, FlushSession ) select_image_files = SelectFile( 'Image Files (*.png *.jpg);;All Files (*)' ) select_image_files.single = False file_names = yield select_image_files file_count = len( file_names ) # end select files # begin create movies import os from sqlalchemy import orm from camelot.core.orm import Session from camelot_example.model import Movie movie_mapper = orm.class_mapper( Movie ) cover_property = movie_mapper.get_property( 'cover' ) storage = cover_property.columns[0].type.storage session = Session() for i, file_name in enumerate(file_names): yield UpdateProgress( i, file_count ) title = os.path.splitext( os.path.basename( file_name ) )[0] stored_file = storage.checkin( six.text_type( file_name ) ) movie = Movie( title = six.text_type( title ) ) movie.cover = stored_file yield FlushSession( session ) # end create movies # begin refresh yield Refresh()
def refresh(self, entity_instance): """Undo the pending changes to the backend and restore the original state""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) if session: if not self.is_deleted( entity_instance ): session.refresh( entity_instance )
def test_fixture( self ): from camelot.model.party import Person from camelot.model.fixture import Fixture session = Session() self.assertEqual( Fixture.find_fixture_key( Person, -1 ), None ) p1 = Person() self.assertEqual( Fixture.find_fixture_key_and_class( p1 ), (None, None) ) session.expunge( p1 ) # insert a new Fixture p2 = Fixture.insert_or_update_fixture( Person, 'test', {'first_name':'Peter', 'last_name':'Principle'}, fixture_class = 'test' ) # see if we can find it back self.assertEqual( Fixture.find_fixture_key( Person, p2.id ), 'test' ) self.assertEqual( Fixture.find_fixture_key_and_class( p2 ), ('test', 'test') ) self.assertEqual( Fixture.find_fixture_keys_and_classes( Person )[p2.id], ('test', 'test') ) # delete the person, and insert it back in the same fixture session.delete( p2 ) session.flush() p3 = Fixture.insert_or_update_fixture( Person, 'test', {'first_name':'Peter', 'last_name':'Principle'}, fixture_class = 'test' ) self.assertNotEqual( p2, p3 ) # remove all fixtures Fixture.remove_all_fixtures( Person )
def get_or_create( cls, username ): session = Session() authentication = session.query( cls ).filter_by( username = username ).first() if not authentication: authentication = cls( username = username ) session.add( authentication ) session.flush() return authentication
def is_persistent(self, obj): """:return: True if the object has a persisted state, False otherwise""" from sqlalchemy.orm.session import Session session = Session.object_session(obj) if session: if obj in session.new: return False if obj in session.deleted: return False return True return False
def set_current_version(cls, fixture_class=None, fixture_version=0, session=None): """Set the current version of the fixtures in the database for a certain fixture class. :param fixture_class: the fixture class for which to get the version :param fixture_version: the version number to which to set the fixture version :param session: the session to use to query the database, if `None` is given, the default Camelot session is used """ if session is None: session = Session() obj = session.query(cls).filter_by(fixture_class=fixture_class).first() if not obj: obj = FixtureVersion(fixture_class=fixture_class, _session=session) obj.fixture_version = fixture_version session.flush()
def find_fixture_keys_and_classes(cls, entity): """Load all fixture keys of a certain entity class in batch. :param entity: the class of the stored data :return: a dictionary mapping the primary key of a on object of type entity to a tuple of type (fixture key, fixture class) """ entity_name = six.text_type(entity.__name__) fixtures = Session().query(cls).filter_by(model=entity_name).all() return dict((f.primary_key, (f.fixture_key, f.fixture_class)) for f in fixtures)
def remove_fixture(cls, entity, fixture_key, fixture_class): """ Remove data from the database, if it was stored through the fixture mechanism. :param entity: the class of the stored data :param fixture_key: a string used to refer to the stored data :param fixture_class: a string used to refer to a group of stored data """ # remove the object itself from sqlalchemy.orm.session import Session obj = cls.find_fixture(entity, fixture_key, fixture_class) obj.delete() Session.object_session(obj).flush() # if this succeeeds, remove the reference reference = cls.find_fixture_reference(entity, fixture_key, fixture_class) reference.delete() Session.object_session(reference).flush()
def is_persistent(self, obj): """:return: True if the object has a persisted state, False otherwise""" from sqlalchemy.orm.session import Session session = Session.object_session( obj ) if session: if obj in session.new: return False if obj in session.deleted: return False return True return False
def get_current_version(cls, fixture_class=None): """Get the current version of the fixtures in the database for a certain fixture class. :param fixture_class: the fixture class for which to get the version """ obj = Session().query(cls).filter_by( fixture_class=fixture_class).first() if obj: return obj.fixture_version return 0
def translate_or_register( cls, source, language ): """Translate source to language, if no translation is found, register the source as to be translated and return the source""" if source: source = unicode( source ) translation = cls.translate( source, language ) if not translation: session = Session() query = session.query( cls ) translation = query.filter_by( source = source, language = language ).first() if not translation: if ( source, language ) not in cls._cache: registered_translation = Translation( source = source, language = language ) cls._cache[( source, language )] = source session.flush( [registered_translation] ) logger.debug( 'registed %s with id %s' % ( source, registered_translation.id ) ) return source return translation return ''
def remove_fixture( cls, entity, fixture_key, fixture_class ): """ Remove data from the database, if it was stored through the fixture mechanism. :param entity: the class of the stored data :param fixture_key: a string used to refer to the stored data :param fixture_class: a string used to refer to a group of stored data """ # remove the object itself from sqlalchemy.orm.session import Session obj = cls.find_fixture( entity, fixture_key, fixture_class) obj.delete() Session.object_session( obj ).flush() # if this succeeeds, remove the reference reference = cls.find_fixture_reference( entity, fixture_key, fixture_class ) reference.delete() Session.object_session( reference ).flush()
def insert_or_update_fixture( cls, entity, fixture_key, values, fixture_class = None ): """Store data in the database through the fixture mechanism, to be able to keep track of it later. :param entity: the class of the stored data :param fixture_key: a string used to refer to the stored data :param values: a dictionary with the data that should be insert or updated in the database :param fixture_class: a string used to refer to a group of stored data :return: an object of type entity, either created or modified """ from sqlalchemy.orm.session import Session obj = cls.find_fixture( entity, fixture_key, fixture_class ) store_fixture = False if not obj: obj = entity() store_fixture = True obj.from_dict( values ) Session.object_session( obj ).flush() if store_fixture: # # The fixture itself might have been deleted, but the reference # might be intact, so this should be updated # reference = cls.find_fixture_reference( entity, fixture_key, fixture_class ) if not reference: reference = cls( model = unicode( entity.__name__ ), primary_key = obj.id, fixture_key = fixture_key, fixture_class = fixture_class ) else: reference.primary_key = obj.id Session.object_session( reference ).flush() return obj
def insert_or_update_fixture(cls, entity, fixture_key, values, fixture_class=None): """Store data in the database through the fixture mechanism, to be able to keep track of it later. :param entity: the class of the stored data :param fixture_key: a string used to refer to the stored data :param values: a dictionary with the data that should be insert or updated in the database :param fixture_class: a string used to refer to a group of stored data :return: an object of type entity, either created or modified """ from sqlalchemy.orm.session import Session obj = cls.find_fixture(entity, fixture_key, fixture_class) store_fixture = False if not obj: obj = entity() store_fixture = True obj.from_dict(values) Session.object_session(obj).flush() if store_fixture: # # The fixture itself might have been deleted, but the reference # might be intact, so this should be updated # reference = cls.find_fixture_reference(entity, fixture_key, fixture_class) if not reference: reference = cls(model=six.text_type(entity.__name__), primary_key=obj.id, fixture_key=fixture_key, fixture_class=fixture_class) else: reference.primary_key = obj.id Session.object_session(reference).flush() return obj
def setUp( self ): metadata.bind = settings.ENGINE() metadata.create_all() self.session = Session() # # insert the value of i in each column of T, that can be searched for # for (i,name), definition in types_to_test.items(): value = self.value_for_type( definition, i ) t = T() setattr( t, name, value ) self.session.flush() self.admin = TAdmin()
def model_run( self, model_context ): import sqlalchemy.exc as sa_exc from camelot.core.orm import Session from camelot.view import action_steps from camelot.view.remote_signals import get_signal_handler LOGGER.debug('session refresh requested') progress_db_message = ugettext('Reload data from database') progress_view_message = ugettext('Update screens') session = Session() signal_handler = get_signal_handler() refreshed_objects = [] expunged_objects = [] # # Loop over the objects one by one to be able to detect the deleted # objects # session_items = len( session.identity_map ) for i, (_key, obj) in enumerate( session.identity_map.items() ): try: session.refresh( obj ) refreshed_objects.append( obj ) except sa_exc.InvalidRequestError: # # this object could not be refreshed, it was probably deleted # outside the scope of this session, so assume it is deleted # from the application its point of view # session.expunge( obj ) expunged_objects.append( obj ) if i%10 == 0: yield action_steps.UpdateProgress( i, session_items, progress_db_message ) yield action_steps.UpdateProgress( text = progress_view_message ) for obj in refreshed_objects: signal_handler.sendEntityUpdate( None, obj ) for obj in expunged_objects: signal_handler.sendEntityDelete( None, obj ) yield action_steps.Refresh()
def setUp(self): from sqlalchemy import MetaData from sqlalchemy.ext.declarative import declarative_base self.metadata = MetaData() self.class_registry = dict() self.Entity = declarative_base(cls=EntityBase, metadata=self.metadata, metaclass=EntityMeta, class_registry=self.class_registry, constructor=None, name='Entity') self.metadata.bind = 'sqlite://' self.session = Session()
def translate_or_register(cls, source, language): """Translate source to language, if no translation is found, register the source as to be translated and return the source""" if source: source = unicode(source) translation = cls.translate(source, language) if not translation: session = Session() query = session.query(cls) translation = query.filter_by(source=source, language=language).first() if not translation: if (source, language) not in cls._cache: registered_translation = Translation(source=source, language=language) cls._cache[(source, language)] = source session.flush([registered_translation]) logger.debug('registed %s with id %s' % (source, registered_translation.id)) return source return translation return ''
def model_run(self, model_context): from camelot.view.action_steps import (SelectFile, UpdateProgress, Refresh, FlushSession) select_files = SelectFile('Txt Files (*.txt *.csv);;All Files (*)') select_files.single = False file_names = yield select_files file_count = len(file_names) import os from camelot.core.orm import Session from rms.Model.ResurseUmane import ResurseUmane from rms.Model.Discipline import Discipline from rms.Model.OreSuplimentare import OreSuplimentare session = Session() for i, file_name in enumerate(file_names): yield UpdateProgress(i, file_count) f = open(file_name) info_prof = f.readline().split(";")[:-1] if session.query(Profesor).filter(Profesor.username == info_prof[0]).first() != None: raise UserException("Exista deja profesorul "+info_prof[2]) prof = Profesor(*info_prof) session.add(prof) for line in f: if line[-1] == ';': vals = line[:-1].split(',') else: vals = line[:-2].split(',') print(vals) try: vals[0] = int(vals[0]) oresup = OreSuplimentare(*vals) oresup.profesor = prof session.add(oresup) except ValueError: disc = Discipline(*vals) disc.titular = prof session.add(disc) yield FlushSession(session) # begin refresh yield Refresh() # end refresh
def delete(self, entity_instance): """Delete an entity instance""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) # # new and deleted instances cannot be deleted # if session: if entity_instance in session.new: session.expunge(entity_instance) elif (entity_instance not in session.deleted) and \ (entity_instance in session): # if the object is not in the session, it might already be deleted history = None # # only if we know the primary key, we can keep track of its history # primary_key = self.mapper.primary_key_from_instance(entity_instance) # # we can only store history of objects where the primary key has only # 1 element # @todo: store history for compound primary keys # if not None in primary_key and len(primary_key)==1: pk = primary_key[0] # save the state before the update from camelot.model.memento import Memento # only register the delete when the camelot model is active if hasattr(Memento, 'query'): from camelot.model.authentication import get_current_authentication history = Memento( model = unicode( self.entity.__name__ ), memento_type = 'before_delete', primary_key = pk, previous_attributes = {}, authentication = get_current_authentication() ) entity_instance.delete() session.flush( [entity_instance] ) if history: Session.object_session( history ).flush( [history] )
def find_fixture_reference(cls, entity, fixture_key, fixture_class=None): """Find the :class:`Fixture` instance that refers to the data stored for a fixture key. :param entity: the class of the stored data :param fixture_key: a string used to refer to the stored data :param fixture_class: a string used to refer to a group of stored data :return: a :class:`Fixture` instance refering to the stored data, or None of no data was found. """ entity_name = six.text_type(entity.__name__) return Session().query(cls).filter_by( model=six.text_type(entity_name), fixture_key=fixture_key, fixture_class=fixture_class).first()
def find_fixture_key(cls, entity, primary_key): """Find the fixture key for an object of type entity with primary key :param entity: the class of the stored data :param primary_key: the integer primary key of the stored data :return: a string with the fixture_key that refers to this data, None if no such data is found """ entity_name = six.text_type(entity.__name__) fixture = Session().query(cls).filter_by( model=entity_name, primary_key=primary_key).first() if fixture: return fixture.fixture_key else: return None
def find_fixture_key_and_class(cls, obj): """Find out if an object was stored in the database through the fixture mechanism and return its `fixture_key` and `fixture_class` :param obj: the object stored in the database :return: (fixture_key, fixture_class) if the object was registered through the fixture mechanism, (None, None) otherwise """ entity_name = six.text_type(obj.__class__.__name__) fixture = Session().query(cls).filter_by(model=entity_name, primary_key=obj.id).first() if fixture: return (fixture.fixture_key, fixture.fixture_class) else: return (None, None)
def model_run(self, model_context): from camelot.view.action_steps import (SelectFile, UpdateProgress, Refresh, FlushSession) select_files = SelectFile('Txt Files (*.txt *.csv);;All Files (*)') select_files.single = False file_names = yield select_files file_count = len(file_names) import os from camelot.core.orm import Session from rms.Model.ResurseUmane import ResurseUmane from rms.Model.Discipline import Discipline from rms.Model.OreSuplimentare import OreSuplimentare session = Session() for i, file_name in enumerate(file_names): yield UpdateProgress(i, file_count) print(file_name) f = open(file_name) info_prof = f.readline().split(";")[:-1] print(info_prof) prof = Profesor(*info_prof) session.add(prof) for line in f: if line[-1] == ';': vals = line[:-1].split(',') else: vals = line[:-2].split(',') print(vals) try: vals[0] = int(vals[0]) oresup = OreSuplimentare(*vals) oresup.profesor = prof session.add(oresup) except ValueError: disc = Discipline(*vals) disc.profesor = prof session.add(disc) yield FlushSession(session) # begin refresh yield Refresh()
def set_current_version(cls, fixture_class=None, fixture_version=0): """Set the current version of the fixtures in the database for a certain fixture class. :param fixture_class: the fixture class for which to get the version :param fixture_version: the version number to which to set the fixture version """ from sqlalchemy.orm.session import Session obj = Session().query(cls).filter_by( fixture_class=fixture_class).first() if not obj: obj = FixtureVersion(fixture_class=fixture_class) obj.fixture_version = fixture_version Session.object_session(obj).flush()
def SessionTransaction(session=None, subtransactions=False, nested=False): """Context manager to run a block within a transaction and roll back if an exception is raised. :param session: a :class:`sqlalchemy.orm.session.Session` object, if `None` is given, the default session is used. """ from camelot.core.orm import Session if session == None: session = Session() transaction = session.begin(subtransactions=subtransactions, nested=nested) try: yield transaction session.commit() except: session.rollback() raise
def flush(self, entity_instance): """Flush the pending changes of this entity instance to the backend""" from sqlalchemy.orm.session import Session session = Session.object_session(entity_instance) if session: objects_to_flush = set([entity_instance]) self._expand_compounding_objects(objects_to_flush) # # Create a list of changes # changes = [] for obj_to_flush in objects_to_flush: if obj_to_flush in session.dirty: modifications = {} try: modifications = self.get_modifications(obj_to_flush) except Exception as e: # todo : there seems to be a bug in sqlalchemy that causes the # get history to fail in some cases logger.error('could not get modifications from object', exc_info=e) primary_key = self.primary_key(obj_to_flush) if modifications and (None not in primary_key): change = memento_change( model=six.text_type(type(obj_to_flush).__name__), memento_type='before_update', primary_key=primary_key, previous_attributes=modifications) changes.append(change) session.flush(objects_to_flush) # # If needed, track the changes # memento = self.get_memento() if changes and memento != None: memento.register_changes(changes)
def model_run(self, model_context): import collections import gc from camelot.core.orm import Session from camelot.view import action_steps from camelot.view.register import dump_register from camelot.view.proxy.collection_proxy import CollectionProxy dump_logger = LOGGER.getChild('dump_state') session = Session() type_counter = collections.defaultdict(int) yield action_steps.UpdateProgress(text=_('Dumping session state')) gc.collect() dump_logger.warn('======= begin register dump =============') dump_register(dump_logger) dump_logger.warn('======= end register dump ===============') for o in session: type_counter[type(o).__name__] += 1 dump_logger.warn('======= begin session dump ==============') for k, v in six.iteritems(type_counter): dump_logger.warn('%s : %s' % (k, v)) dump_logger.warn('======= end session dump ==============') yield action_steps.UpdateProgress(text=_('Dumping item model state')) dump_logger.warn('======= begin item model dump =========') for o in gc.get_objects(): if isinstance(o, CollectionProxy): dump_logger.warn('%s is used by :' % (six.text_type(o))) for r in gc.get_referrers(o): dump_logger.warn(' ' + type(r).__name__) for rr in gc.get_referrers(r): dump_logger.warn(' ' + type(rr).__name__) dump_logger.warn('======= end item model dump ===========')
def model_run(self, model_context): from camelot.view.action_steps import (SelectFile, UpdateProgress, Refresh, FlushSession) select_files = SelectFile('Txt Files (*.txt *.csv);;All Files (*)') select_files.single = False file_names = yield select_files file_count = len(file_names) import os from camelot.core.orm import Session from rms.Model.Orar import Orar session = Session() for i, file_name in enumerate(file_names): yield UpdateProgress(i, file_count) title = os.path.splitext(os.path.basename(file_name))[0] print(file_name) for line in open(file_name): vals = line.split(';')[:-1] if len(vals) != 8: raise ImportException("Fisierul nu e dat bine") if vals[2] not in ['0', '1', '2']: raise ImportException("Frecventa nu e data bine") print(vals) orar = Orar(*vals) print(orar) session.add(orar) disc = session.query(Discipline).filter(Discipline.disc==orar.disc).first() if disc: orar.disciplina = disc session.flush() yield FlushSession(session) # begin refresh yield Refresh() # end refresh
def model_run(self, model_context): import sqlalchemy.exc as sa_exc from camelot.core.orm import Session from camelot.view import action_steps from camelot.view.remote_signals import get_signal_handler LOGGER.debug('session refresh requested') progress_db_message = ugettext('Reload data from database') progress_view_message = ugettext('Update screens') session = Session() signal_handler = get_signal_handler() refreshed_objects = [] expunged_objects = [] # # Loop over the objects one by one to be able to detect the deleted # objects # session_items = len(session.identity_map) for i, (_key, obj) in enumerate(six.iteritems(session.identity_map)): try: session.refresh(obj) refreshed_objects.append(obj) except sa_exc.InvalidRequestError: # # this object could not be refreshed, it was probably deleted # outside the scope of this session, so assume it is deleted # from the application its point of view # session.expunge(obj) expunged_objects.append(obj) if i % 10 == 0: yield action_steps.UpdateProgress(i, session_items, progress_db_message) yield action_steps.UpdateProgress(text=progress_view_message) for obj in refreshed_objects: signal_handler.sendEntityUpdate(self, obj) for obj in expunged_objects: signal_handler.sendEntityDelete(self, obj) yield action_steps.Refresh()
# {{{ boilerplate from camelot.core.orm import Session import os import sys sys.path.append(os.environ["GRADEBOOK_ROOT"]) import main # noqa from camelot.core.conf import settings settings.setup_model() # }}} session = Session() from gradebook.model import (Course, Student, StudentContactInfo) course, = session.query(Course).all() import csv with open('class-list.csv', 'rb') as csvfile: reader = csv.DictReader(csvfile, delimiter=";") for row in reader: print row ln = row["Last"] fn = row["First"] student = Student(first_name=unicode(fn.strip()), last_name=unicode(ln.strip()), user_name=unicode(row["NetID"]), course=course)
def expunge(self, entity_instance): """Expunge the entity from the session""" from sqlalchemy.orm.session import Session session = Session.object_session( entity_instance ) if session: session.expunge( entity_instance )
def run(self): self.query_session_2 = A.query.session self.orm_session_2 = Session()
# {{{ boilerplate from camelot.core.orm import Session import os, sys sys.path.append(os.environ["GRADEBOOK_ROOT"]) import main from camelot.core.conf import settings settings.setup_model() # }}} session = Session() from gradebook.model import Course for name in session.query(Course.name): print name session.flush()
def get_filter_data(self, admin): """ :return: a :class:`filter_data` object """ from sqlalchemy.sql import select from camelot.core.orm import Session session = Session() filter_names = [] joins = [] # # in case of inheritance, use the local table to be able to join, # otherwise use the mapped table, to be able to filter on views # if admin.mapper!=admin.mapper.base_mapper: table = admin.mapper.local_table else: table = admin.mapper.mapped_table path = self.attribute.split('.') for field_name in path: attributes = admin.get_field_attributes(field_name) filter_names.append(attributes['name']) # @todo: if the filter is not on an attribute of the relation, but on the relation itselves if 'target' in attributes: admin = attributes['admin'] joins.append(field_name) if attributes['direction'] == 'manytoone': table = admin.entity.table.join( table ) else: table = admin.entity.table col = getattr( admin.entity, field_name ) query = select([col], distinct=True, order_by=col.asc()).select_from(table) def create_decorator(col, attributes, value, joins): def decorator(q): if joins: q = q.join( *joins, aliased=True) if 'precision' in attributes: delta = pow( 10, -1*attributes['precision']) return q.filter( sql.and_(col < value+delta, col > value-delta) ) return q.filter(col==value) return decorator options = [ filter_option( name = _('All'), value = Filter.All, decorator = lambda q:q ) ] for value in session.execute(query): if 'to_string' in attributes: option_name = attributes['to_string'](value[0]) else: option_name = value[0] if attributes.get( 'translate_content', False ): option_name = _( option_name ) options.append( filter_option( name = option_name, value = value[0], decorator = create_decorator(col, attributes, value[0], joins) ) ) return filter_data( name = filter_names[0], options = options, default = self.default )