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_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 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 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 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_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 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 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 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 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 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 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 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 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 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 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 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 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 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, 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 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): 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()
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 get_query(self): """:return: an sqlalchemy query for all the objects that should be displayed in the table or the selection view. Overwrite this method to change the default query, which selects all rows in the database. """ return Session().query(self.entity)
def tearDown( self ): Session().expunge_all()
def run(self): self.query_session_2 = A.query.session self.orm_session_2 = Session()
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.mapper.mapped_table.join( table ) else: table = admin.mapper.mapped_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 )
def session(self): return Session()
def add(self, obj): """Adds the entity instance to the default session, if it is not yet attached to a session""" session = Session.object_session(obj) if session == None: Session().add(obj)