def setup_method(self, method): self.Model = declarative_base() make_versioned(options=self.options) driver = os.environ.get('DB', 'sqlite') driver = get_driver_name(driver) versioning_manager.plugins = self.plugins versioning_manager.transaction_cls = self.transaction_cls versioning_manager.user_cls = self.user_cls self.engine = create_engine(get_dns_from_driver(driver)) # self.engine.echo = True self.connection = self.engine.connect() self.create_models() sa.orm.configure_mappers() if hasattr(self, 'Article'): self.ArticleVersion = version_class(self.Article) if hasattr(self, 'Tag'): try: self.TagVersion = version_class(self.Tag) except ClassNotVersioned: pass self.create_tables() Session = sessionmaker(bind=self.connection) self.session = Session(autoflush=False)
def setup_method(self, method): self.Model = declarative_base() make_versioned(options=self.options) driver = os.environ.get('DB', 'sqlite') self.driver = get_driver_name(driver) versioning_manager.plugins = self.plugins versioning_manager.transaction_cls = self.transaction_cls versioning_manager.user_cls = self.user_cls self.engine = create_engine(get_dns_from_driver(self.driver)) # self.engine.echo = True self.create_models() sa.orm.configure_mappers() self.connection = self.engine.connect() if hasattr(self, 'Article'): try: self.ArticleVersion = version_class(self.Article) except ClassNotVersioned: pass if hasattr(self, 'Tag'): try: self.TagVersion = version_class(self.Tag) except ClassNotVersioned: pass self.create_tables() Session = sessionmaker(bind=self.connection) self.session = Session(autoflush=False) if driver == 'postgres-native': self.session.execute('CREATE EXTENSION IF NOT EXISTS hstore')
def get_office_revision(transaction_id, business_id) -> dict: """Consolidates all office changes upto the given transaction id.""" offices_json = {} address_version = version_class(Address) offices_version = version_class(Office) offices = db.session.query(offices_version) \ .filter(offices_version.transaction_id <= transaction_id) \ .filter(offices_version.operation_type != 2) \ .filter(offices_version.business_id == business_id) \ .filter(or_(offices_version.end_transaction_id == None, # pylint: disable=singleton-comparison # noqa: E711,E501; offices_version.end_transaction_id > transaction_id)) \ .order_by(offices_version.transaction_id).all() for office in offices: offices_json[office.office_type] = {} addresses_list = db.session.query(address_version) \ .filter(address_version.transaction_id <= transaction_id) \ .filter(address_version.operation_type != 2) \ .filter(address_version.office_id == office.id) \ .filter(or_(address_version.end_transaction_id == None, # pylint: disable=singleton-comparison # noqa: E711,E501; address_version.end_transaction_id > transaction_id)) \ .order_by(address_version.transaction_id).all() for address in addresses_list: offices_json[office.office_type][f'{address.address_type}Address'] = \ VersionedBusinessDetailsService.address_revision_json(address) return offices_json
def test_sa_inheritance_with_no_distinct_table_has_right_translation_class(self): class_ = version_class(self.BaseModel) assert class_.__name__ == 'BaseModelVersion' assert class_.__table__.name == 'base_model_version' class_ = version_class(self.FirstLevel) assert class_.__name__ == 'FirstLevelVersion' assert class_.__table__.name == 'first_level_version' class_ = version_class(self.SecondLevel) assert class_.__name__ == 'SecondLevelVersion' assert class_.__table__.name == 'first_level_version'
def test_sa_inheritance_with_no_distinct_table_has_right_translation_class( self): class_ = version_class(self.BaseModel) assert class_.__name__ == 'BaseModelVersion' assert class_.__table__.name == 'base_model_version' class_ = version_class(self.FirstLevel) assert class_.__name__ == 'FirstLevelVersion' assert class_.__table__.name == 'first_level_version' class_ = version_class(self.SecondLevel) assert class_.__name__ == 'SecondLevelVersion' assert class_.__table__.name == 'first_level_version'
def clear(ctx, raise_on_error=True, only=None): """Clear all record data in publications repository.""" RecordsBuckets.query.delete() RecordMetadata.query.delete() PersistentIdentifier.query.delete() ObjectVersion.query.delete() FileInstance.query.delete() Bucket.query.delete() version_cls = version_class(RecordMetadata) version_cls.query.delete() versioning_manager.transaction_cls.query.delete() # RecordReference.query.delete() # ReferencingRecord.query.delete() # ClassName.query.delete() subprocess.call([ 'oarepo', 'index', 'destroy', '--yes-i-know', '--force' ]) subprocess.call([ 'oarepo', 'index', 'init', '--force' ]) db.session.commit()
def project_application(org_slug, project_slug, app_slug): organization = Organization.query.filter_by(slug=org_slug).first() if organization is None: abort(404) project = Project.query.filter_by(organization_id=organization.id, slug=project_slug).first() if project is None: abort(404) application = Application.query.filter_by(project_id=project.id, slug=app_slug).first() if application is None: abort(404) pod_class_info = '<table class="table"><tr><th>Class</th><th>CPU</th><th>Mem</th></tr>' for pod_class, parameters in pod_classes.items(): pod_class_info += f'<tr><td>{pod_class}</td><td>{parameters["cpu"]["requests"]}</td><td>{parameters["memory"]["requests"]}</td></tr>' pod_class_info += '</table>' scale_form = ApplicationScaleForm() scale_form.application_id.data = str(application.id) return render_template( 'user/project_application.html', application=application, deploy_form=ReleaseDeployForm(), scale_form=scale_form, view_releases=version_class(Release).query.filter_by(application_id=application.id).order_by(desc(version_class(Release).version_id)).limit(5), DEFAULT_POD_CLASS=DEFAULT_POD_CLASS, pod_classes=pod_classes, pod_class_info=pod_class_info, )
def get_party_role_revision(transaction_id, business_id, is_ia_or_after=False, role=None) -> dict: """Consolidates all party changes upto the given transaction id.""" party_role_version = version_class(PartyRole) party_roles = db.session.query(party_role_version)\ .filter(party_role_version.transaction_id <= transaction_id) \ .filter(party_role_version.operation_type != 2) \ .filter(party_role_version.business_id == business_id) \ .filter(or_(role == None, # pylint: disable=singleton-comparison # noqa: E711,E501; party_role_version.role == role)) \ .filter(or_(party_role_version.end_transaction_id == None, # pylint: disable=singleton-comparison # noqa: E711,E501; party_role_version.end_transaction_id > transaction_id)) \ .order_by(party_role_version.transaction_id).all() parties = [] for party_role in party_roles: if party_role.cessation_date is None: party_role_json = VersionedBusinessDetailsService.party_role_revision_json( transaction_id, party_role, is_ia_or_after) if 'roles' in party_role_json and (party := next( (x for x in parties if x['officer']['id'] == party_role_json['officer']['id']), None)): party['roles'].extend(party_role_json['roles']) else: parties.append(party_role_json)
def reset_datas(cfg_file, col_name, read_datas=read_datas, skip_first=False, clean=True): datas = read_file(cfg_file, read_datas, skip_first) count = 0 length = len(datas) if len(datas): # 清空数据 if clean == "true": db.session.query(col_name).delete() version = version_class(col_name) db.session.query(version).delete() db.session.commit() for data in datas: try: inst = col_name(**data) db.session.add(inst) count += 1 except Exception as e: logging.warn(e) if length != count: logging.warn("not all the datas can import") return try: db.session.commit() except Exception as e: logging.warn(e) db.session.rollback() return count
def get(widget_id, key): history = request.args.get('history') if history == "true": OutputClass = version_class(Dictionary) else: OutputClass = Dictionary query = db.session.query(OutputClass).filter_by(widget_id=widget_id, key=key) if history == "true": query = query.filter(OutputClass.value_mod) query = query.order_by(OutputClass.last_updated.desc()) date_before= request.args.get('datebefore') if date_before != None: query = query.filter(OutputClass.last_updated <= date_before) limit = request.args.get('limit') if limit != None: query = query.limit(limit) results = query.all() if len(results) == 0: raise NastyError("not_found", "No results found") return json.jsonify(results)
def get_table_version(db: Session) -> int: version = version_class(TypePhotoDB) last_changed = db.query(version).order_by(desc(version.transaction_id)).limit(1) if last_changed.count() > 0: return last_changed[0].transaction_id else: return -1
def is_allowed_with_user(self, related_user=True, current=True): # Todo: 如果有对特殊角色的权限设置, 可以在此进行判断 # related_user: 使用相关用户还是允许用户判断 # current: 判断related_user与当前用户比较还是与制单人进行比较 version = version_class(self.model.__class__) query = version.query.filter(version.id == self.model.id, version.auditStatus == InitialState) index = query[-1].transaction_id if query else None if not index: return False inst = query[-1] if related_user: if inst.relatedUser != current_user: return False return True user_id = current_user.id if current else inst.relatedUser_id status = [ReviewedFailure, ApprovedFailure, SecApprovalFailure] query = version.query.filter(version.id == self.model.id, version.auditStatus.in_(status)) tmp_index = query[-1].transaction_id if query.count() else 0 index = index if index > tmp_index else tmp_index query = version.query.filter(version.id == self.model.id, version.allowedUser_id == user_id, version.auditStatus == self.model.status, version.transaction_id >= index).all() if not query: return False return True
def get(self): UserNewVersion = version_class(User_newModel) users_list = UserNewVersion.query.all() users=[] # len=len(users_list) # print(users_list) for user in users_list: users.append({ 'id':user.id, 'name':user.name, 'email':user.email, 'mobile':user.mobile, 'country_id':user.country_id, 'state_id':user.state_id, 'city_id':user.city_id, 'hobbies':user.hobbies, 'gender':user.gender, 'address':user.address, 'transaction_id':user.transaction_id, 'end_transaction_id':user.end_transaction_id, 'operation_type':user.operation_type, 'user_modified':user.user_modified }) # print(users) return Response(json.dumps(users))
def _get_data(self, dt): """ SELECT t.client_id AS accounts_client_id, sum((t.account_budget - t.remaining_account_budget) * t.exchange_rate) AS sum_1 FROM ( SELECT DISTINCT ON (adwords_id) * FROM accounts_version WHERE accounts_version.updated_at < now_utc() ORDER BY accounts_version.adwords_id, accounts_version.updated_at DESC ) AS t GROUP BY t.client_id ORDER BY t.client_id """ AccountVersion = version_class(Account) t = AccountVersion.query.distinct(AccountVersion.adwords_id)\ .filter(AccountVersion.updated_at < dt)\ .order_by(AccountVersion.adwords_id, AccountVersion.updated_at.desc())\ .subquery('t') # Have to manually define the hybrid in subqueries hyb = func.sum((t.c.account_budget - t.c.remaining_account_budget) * t.c.exchange_rate) q = db.session.query(t.c.client_id, hyb).group_by(t.c.client_id) return q.all()
def get_data(self): """Do not pass AccountVersion objects to jinja because we need updated information on each account. Return in the order of when the account was suspended DESC. """ AccountVersion = version_class(Account) week_ago = datetime.now(pytz.utc) - timedelta(days=7) order = [] account_versions = {} for av in AccountVersion.query.filter( and_( AccountVersion.status_mod == True, # noqa AccountVersion.updated_at > week_ago, AccountVersion.status.in_([ AccountStatus.SUSPENDED, AccountStatus.ATTENTION ]))).order_by(AccountVersion.updated_at.desc()): order.append(av.adwords_id) account_versions[av.adwords_id] = av accounts = {} for account in Account.query.filter( Account.adwords_id.in_(account_versions.keys())): accounts[account.adwords_id] = account for adwords_id in order: yield (accounts[adwords_id], account_versions[adwords_id])
def get_public_work_changes_from(db: Session, public_work_version: int) -> list: versioned_class = version_class(PublicWorkDB) changes_list = db.query(versioned_class).filter( versioned_class.transaction_id > public_work_version).order_by( desc(versioned_class.transaction_id)) changes_dict = {} for change in changes_list: if change.id not in changes_dict: if change.operation_type == Operation.DELETE: changes_dict[change.id] = PublicWorkDiff( id=change.id, operation=change.operation_type) else: try: public_work = PublicWorkDiff( id=change.id, name=change.name, type_work_flag=change.type_work_flag, address=change.address, operation=change.operation_type) if change.user_status: public_work.user_status = change.user_status changes_dict[change.id] = public_work except Exception: print("Exception when parsing the public work") return list(changes_dict.values())
def test_versioned_table_structure(self): table = version_class(self.Article).__table__ assert 'id' in table.c assert 'name' in table.c assert 'content' in table.c assert 'description' in table.c assert 'transaction_id' in table.c assert 'operation_type' in table.c
def test_versioned_table_structure(self): table = version_class(self.Article).__table__ assert 'id' in table.c assert 'name' in table.c assert 'content' in table.c assert 'description'in table.c assert 'transaction_id' in table.c assert 'operation_type' in table.c
def test_something(self): table = version_class(self.Article).__table__ self._insert({ 'id': 1, 'transaction_id': 1, 'end_transaction_id': 2, 'name': u'Article 1', 'name_mod': False, 'operation_type': 1, }) self._insert({ 'id': 1, 'transaction_id': 2, 'end_transaction_id': 4, 'name': u'Article 1', 'name_mod': False, 'operation_type': 2, }) self._insert({ 'id': 2, 'transaction_id': 3, 'end_transaction_id': 5, 'name': u'Article 2', 'name_mod': False, 'operation_type': 1, }) self._insert({ 'id': 1, 'transaction_id': 4, 'end_transaction_id': None, 'name': u'Article 1 updated', 'name_mod': False, 'operation_type': 2, }) self._insert({ 'id': 2, 'transaction_id': 5, 'end_transaction_id': None, 'name': u'Article 2', 'name_mod': False, 'operation_type': 2, }) update_property_mod_flags(table, ['name'], conn=self.session) rows = self.session.execute( 'SELECT * FROM article_version ORDER BY transaction_id').fetchall( ) assert rows[0].transaction_id == 1 assert rows[0].name_mod assert rows[1].transaction_id == 2 assert not rows[1].name_mod assert rows[2].transaction_id == 3 assert rows[2].name_mod assert rows[3].transaction_id == 4 assert rows[3].name_mod assert rows[4].transaction_id == 5 assert not rows[4].name_mod
def test_something(self): table = version_class(self.Article).__table__ self._insert( { 'id': 1, 'transaction_id': 1, 'name': u'Article 1', 'operation_type': 1, } ) self._insert( { 'id': 1, 'transaction_id': 2, 'name': u'Article 1 updated', 'operation_type': 2, } ) self._insert( { 'id': 2, 'transaction_id': 3, 'name': u'Article 2', 'operation_type': 1, } ) self._insert( { 'id': 1, 'transaction_id': 4, 'name': u'Article 1 updated (again)', 'operation_type': 2, } ) self._insert( { 'id': 2, 'transaction_id': 5, 'name': u'Article 2 updated', 'operation_type': 2, } ) update_end_tx_column(table, conn=self.session) rows = self.session.execute( 'SELECT * FROM article_version ORDER BY transaction_id' ).fetchall() assert rows[0].transaction_id == 1 assert rows[0].end_transaction_id == 2 assert rows[1].transaction_id == 2 assert rows[1].end_transaction_id == 4 assert rows[2].transaction_id == 3 assert rows[2].end_transaction_id == 5 assert rows[3].transaction_id == 4 assert rows[3].end_transaction_id is None assert rows[4].transaction_id == 5 assert rows[4].end_transaction_id is None
def test_update_end_transaction_id(self): table = version_class(self.Article).__table__ self._insert( { 'id': 1, 'transaction_id': 1, 'name': u'Article 1', 'operation_type': 1, } ) self._insert( { 'id': 1, 'transaction_id': 2, 'name': u'Article 1 updated', 'operation_type': 2, } ) self._insert( { 'id': 2, 'transaction_id': 3, 'name': u'Article 2', 'operation_type': 1, } ) self._insert( { 'id': 1, 'transaction_id': 4, 'name': u'Article 1 updated (again)', 'operation_type': 2, } ) self._insert( { 'id': 2, 'transaction_id': 5, 'name': u'Article 2 updated', 'operation_type': 2, } ) update_end_tx_column(table, conn=self.session) rows = self.session.execute( 'SELECT * FROM article_version ORDER BY transaction_id' ).fetchall() assert rows[0].transaction_id == 1 assert rows[0].end_transaction_id == 2 assert rows[1].transaction_id == 2 assert rows[1].end_transaction_id == 4 assert rows[2].transaction_id == 3 assert rows[2].end_transaction_id == 5 assert rows[3].transaction_id == 4 assert rows[3].end_transaction_id is None assert rows[4].transaction_id == 5 assert rows[4].end_transaction_id is None
def get_revision(endpoint, pid_value, transaction_id, rec_uuid): """Get the revision of given record (uuid)""" RecordMetadataVersion = version_class(RecordMetadata) revision = RecordMetadataVersion.query.with_entities( RecordMetadataVersion.json).filter( RecordMetadataVersion.transaction_id == transaction_id, RecordMetadataVersion.id == rec_uuid).one() return jsonify(revision.json)
def get_deleted(): current_app.logger.info(f"/deleted accessed {g.request_user.email}") deleted_since = request.args.get('deleted_since', None) deleted_since = http.parse_date(deleted_since) deleted_objects = { "surveys": [], "responses": [], "case_definitions": [], "cases": [] } endpoints = [{ 'name': 'surveys', 'model': models.Survey, }, { 'name': 'responses', 'model': models.SurveyResponse, }, { 'name': 'case_definitions', 'model': models.CaseDefinition, }, { 'name': 'cases', 'model': models.Case, }, { 'name': 'activities', 'model': models.Activity }, { 'name': 'activity_definitions', 'model': models.ActivityDefinition }] def gen_item(item): return { 'id': item.id, 'deleted_at': item.transaction.issued_at.isoformat() } for e in endpoints: model_version_class = version_class(e['model']) query = app.db.session.query(model_version_class) query = query.filter_by(operation_type=Operation.DELETE) deleted = query.all() if deleted_since: deleted = [ i for i in deleted if i.transaction.issued_at >= deleted_since ] deleted_objects[e['name']] = [gen_item(d) for d in deleted] return jsonify(deleted_objects), 200
def test_change_single_entity(self): self.article = self.Article() self.article.name = u'Some article' self.article.content = u'Some content' self.session.add(self.article) self.session.commit() tx = self.article.versions[0].transaction assert tx.changed_entities == { version_class(self.article.__class__): [self.article.versions[0]] }
def get_address_revision(transaction_id, address_id) -> dict: """Consolidates all party changes upto the given transaction id.""" address_version = version_class(Address) address = db.session.query(address_version) \ .filter(address_version.transaction_id <= transaction_id) \ .filter(address_version.operation_type != 2) \ .filter(address_version.id == address_id) \ .filter(or_(address_version.end_transaction_id == None, # pylint: disable=singleton-comparison # noqa: E711,E501; address_version.end_transaction_id > transaction_id)) \ .order_by(address_version.transaction_id).one_or_none() return address
def get_party_revision(transaction_id, party_role_revision) -> dict: """Consolidates all party changes upto the given transaction id.""" party_version = version_class(Party) party = db.session.query(party_version) \ .filter(party_version.transaction_id <= transaction_id) \ .filter(party_version.operation_type != 2) \ .filter(party_version.id == party_role_revision.party_id) \ .filter(or_(party_version.end_transaction_id == None, # pylint: disable=singleton-comparison # noqa: E711,E501; party_version.end_transaction_id > transaction_id)) \ .order_by(party_version.transaction_id).one_or_none() return party
def get_business_revision(transaction_id, business) -> dict: """Consolidates the business info as of a particular transaction.""" business_version = version_class(Business) business_revision = db.session.query(business_version) \ .filter(business_version.transaction_id <= transaction_id) \ .filter(business_version.operation_type != 2) \ .filter(business_version.id == business.id) \ .filter(or_(business_version.end_transaction_id == None, # pylint: disable=singleton-comparison # noqa: E711,E501; business_version.end_transaction_id > transaction_id)) \ .order_by(business_version.transaction_id).one_or_none() return VersionedBusinessDetailsService.business_revision_json( business_revision, business.json())
def get_history(self): version = version_class(self.model) query = version.query.filter(version.nextCheckDate != None, version.nextCheckDate != '').order_by( version.nextCheckDate).all() datas = [] for item in query: if 'nextCheckDate' in item.changeset.keys( ) or 'checkRecord' in item.changeset.keys(): datas.append(item) page = request.args.get('page', 0, type=int) return len(datas), datas[page * 20:page * 20 + 20]
def test_assigns_foreign_keys_for_versions(self): article = self.Article() article.name = u'Some article' article.content = u'Some content' article.tags.append(self.Tag(name=u'some tag')) self.session.add(article) self.session.commit() cls = version_class(self.Tag) version = self.session.query(cls).first() assert version.name == u'some tag' assert version.id == 1 assert version.article_id == 1
def get_business_revision_after_filing(filing_id, business_id) -> dict: """Consolidates the business info as of a particular transaction.""" business = Business.find_by_internal_id(business_id) filing = Filing.find_by_id(filing_id) business_version = version_class(Business) business_revision = db.session.query(business_version) \ .filter(business_version.transaction_id > filing.transaction_id) \ .filter(business_version.operation_type != 2) \ .filter(business_version.id == business.id) \ .order_by(business_version.transaction_id).one_or_none() return VersionedBusinessDetailsService.business_revision_json( business_revision, business.json())
def get_business_revision_before_filing(filing_id, business_id) -> dict: """Consolidates the business info of the previous filing.""" business = Business.find_by_internal_id(business_id) filing = Filing.find_by_id(filing_id) business_version = version_class(Business) business_revision = db.session.query(business_version) \ .filter(business_version.transaction_id < filing.transaction_id) \ .filter(business_version.operation_type != 2) \ .filter(business_version.id == business.id) \ .order_by(business_version.transaction_id.desc()).first() return VersionedBusinessDetailsService.business_revision_json( business_revision, business.json())
def get_revision(endpoint, pid_value, transaction_id, rec_uuid): """Get the revision of given record (uuid)""" RecordMetadataVersion = version_class(RecordMetadata) revision = RecordMetadataVersion.query.with_entities( RecordMetadataVersion.json ).filter( RecordMetadataVersion.transaction_id == transaction_id, RecordMetadataVersion.id == rec_uuid ).one() return jsonify(revision.json)
def sorted_tables(cls, versioned=False): # TODO SQLAlchemy-Continuum versioning is not included here!!! # use metadata somehow # or include version_class operator... for c in cls.sorted_subclasses(): yield c.__table__ # sqlalchemy_continuum extension if hasattr(c, '__versioned__'): yield (version_class(c).__table__)
def show_user_log(username, page=1): MAX_ENTRIES_PER_PAGE = 10 Transaction = versioning_manager.transaction_cls VersionClassCVE = version_class(CVE) VersionClassGroup = version_class(CVEGroup) VersionClassAdvisory = version_class(Advisory) pagination = (db.session.query(Transaction, VersionClassCVE, VersionClassGroup, VersionClassAdvisory) .outerjoin(VersionClassCVE, Transaction.id == VersionClassCVE.transaction_id) .outerjoin(VersionClassGroup, Transaction.id == VersionClassGroup.transaction_id) .outerjoin(VersionClassAdvisory, Transaction.id == VersionClassAdvisory.transaction_id) .join(User) .filter(User.name == username) .order_by(Transaction.issued_at.desc()) ).paginate(page, MAX_ENTRIES_PER_PAGE, True) return render_template('log/log.html', title=f'User {username} - log', username=username, pagination=pagination, CVE=CVE, CVEGroup=CVEGroup)
def get_revision(transaction_id, rec_uuid): """Get the revision of given record (uuid)""" try: RecordMetadataVersion = version_class(RecordMetadata) revision = (RecordMetadataVersion.query.with_entities( RecordMetadataVersion.json).filter( RecordMetadataVersion.transaction_id == transaction_id, RecordMetadataVersion.id == rec_uuid, ).one()) return jsonify(revision.json) except Exception: raise EditorGetRevisionError
def test_mod_properties_with_delete(self): user = self.User(name=u'John') self.session.add(user) self.session.commit() self.session.delete(user) self.session.commit() UserVersion = version_class(self.User) version = ( self.session .query(UserVersion) .order_by(sa.desc(UserVersion.transaction_id)) ).first() assert version.age_mod assert version.name_mod
def test_create_file_version(monkeypatch, first_version_node, middle_version_node, current_version_node): from sqlalchemy_continuum import version_class from core import File NodeToFileVersion = version_class(NodeToFile) FileVersion = version_class(File) def _version_class(clz): if clz == NodeToFile: return NodeToFileVersion elif clz == File: return FileVersion monkeypatch.setattr(version_migration, "version_class", _version_class) Transaction = versioning_manager.transaction_cls remove_versioning() first = first_version_node middle = middle_version_node current = current_version_node first_files = [FileFactory()] first.files.extend(first_files) middle_files = [FileFactory()] middle.files.extend(middle_files) current_files = [FileFactory()] current.files.extend(current_files) transaction = Transaction() version_migration.create_file_versions(first, middle, transaction) transaction2 = Transaction() version_migration.create_file_versions(middle, current, transaction2)
def find_by_holding(cls, **kwargs): """Find item versions based on their holdings information. Every given kwarg will be queried as a key-value pair in the items holding. :returns: List[(UUID, version_id)] with `version_id` as used by `RecordMetadata.version_id`. """ def _get_filter_clause(obj, key, value): val = obj[key].astext CASTS = { bool: lambda x: cast(x, BOOLEAN), int: lambda x: cast(x, INTEGER), datetime.date: lambda x: cast(x, DATE), } if (not isinstance(value, six.string_types) and isinstance(value, collections.Sequence)): if len(value) == 2: return CASTS[type(value[0])](val).between(*value) raise ValueError('Too few/many values for a range query. ' 'Range query requires two values.') return CASTS.get(type(value), lambda x: x)(val) == value RecordMetadataVersion = version_class(RecordMetadata) data = type_coerce(RecordMetadataVersion.json, JSONB) path = ('_circulation', 'holdings') subquery = db.session.query( RecordMetadataVersion.id.label('id'), RecordMetadataVersion.version_id.label('version_id'), func.json_array_elements(data[path]).label('obj') ).subquery() obj = type_coerce(subquery.c.obj, JSONB) query = db.session.query( RecordMetadataVersion.id, RecordMetadataVersion.version_id ).filter( RecordMetadataVersion.id == subquery.c.id, RecordMetadataVersion.version_id == subquery.c.version_id, *(_get_filter_clause(obj, k, v) for k, v in kwargs.items()) ) for result in query: yield result
def upgrade(): op.add_column('volunteer', sa.Column('over_18', sa.Boolean(), nullable=False, server_default=expression.false())) op.add_column('volunteer_version', sa.Column('over_18', sa.Boolean(), autoincrement=False, nullable=True)) bind = op.get_bind() session = sa.orm.Session(bind=bind) for volunteer in session.query(Volunteer): volunteer.over_18 = (volunteer.age >= 18) # include deleted records for version in session.query(version_class(Volunteer)): version.over_18 = (version.age >= 18) session.commit() op.drop_column('volunteer', 'age') op.drop_column('volunteer_version', 'age')
def downgrade(): op.add_column('volunteer_version', sa.Column('age', sa.INTEGER(), autoincrement=False, nullable=True)) op.add_column('volunteer', sa.Column('age', sa.INTEGER(), autoincrement=False, nullable=False, server_default=text('0'))) # No clean downgrade, as we want to get rid of the data bind = op.get_bind() session = sa.orm.Session(bind=bind) for volunteer in session.query(Volunteer): volunteer.age = 18 if volunteer.over_18 else 17 # include deleted records for version in session.query(version_class(Volunteer)): version.age = 18 if version.over_18 else 17 session.commit() op.drop_column('volunteer_version', 'over_18') op.drop_column('volunteer', 'over_18')
def test_previous_for_deleted_parent(self): item = self.TextItem() item.name = u'Some item' item.content = u'Some content' self.session.add(item) self.session.commit() self.session.delete(item) self.session.commit() TextItemVersion = version_class(self.TextItem) versions = ( self.session.query(TextItemVersion) .order_by( getattr( TextItemVersion, self.options['transaction_column_name'] ) ) ).all() assert versions[1].previous.name == u'Some item'
def _insert(self, values): table = version_class(self.Article).__table__ stmt = table.insert().values(values) self.session.execute(stmt)
def test_primary_keys_not_included(self): UserVersion = version_class(self.User) assert 'id_mod' not in UserVersion.__table__.c
def test_each_column_generates_additional_mod_column(self): UserVersion = version_class(self.User) assert 'name_mod' in UserVersion.__table__.c column = UserVersion.__table__.c['name_mod'] assert not column.nullable assert isinstance(column.type, sa.Boolean)
def test_created_tables_retain_schema(self): table = version_class(self.Article).__table__ assert table.schema is not None assert table.schema == self.Article.__table__.schema
def test_column_reflection(self): assert '_id' in version_class(self.TextItem).__table__.c
def test_datetime_columns_with_defaults_excluded_by_default(self): assert ( 'created_at' in version_class(self.Article).__table__.c )
def test_transaction_id_column_not_nullable(self): assert self.Article.__table__.c.name.nullable is False table = version_class(self.Article).__table__ assert table.c.transaction_id.nullable is False
def test_primary_keys_remain_not_nullable(self): assert self.Article.__table__.c.name.nullable is False table = version_class(self.Article).__table__ assert table.c.id.nullable is False
def test_removes_not_null_constraints(self): assert self.Article.__table__.c.name.nullable is False table = version_class(self.Article).__table__ assert table.c.name.nullable is True
def test_removes_autoincrementation(self): table = version_class(self.Article).__table__ assert table.c.id.autoincrement is False
def setup_method(self, method): TestCase.setup_method(self, method) self.TextItemVersion = version_class(self.TextItem) self.ArticleVersion = version_class(self.Article) self.BlogPostVersion = version_class(self.BlogPost)
def test_parent_class_for_version_class(self): ArticleVersion = version_class(self.Article) assert parent_class(ArticleVersion) == self.Article
def test_datetime_exclusion_only_applies_to_datetime_types(self): assert ( 'is_deleted' in version_class(self.Article).__table__.c )
def test_tsvector_typed_columns_excluded_by_default(self): assert ( 'search_vector' not in version_class(self.Article).__table__.c )
def test_takes_out_onupdate_triggers(self): table = version_class(self.Article).__table__ assert table.c.last_update.onupdate is None
def test_excluded_columns_not_included_in_version_class(self): cls = version_class(self.TextItem) manager = cls._sa_class_manager assert 'content' not in manager.keys()
def test_does_not_make_composite_primary_keys_not_nullable(self): TeamMemberVersion = version_class(self.TeamMember) assert not TeamMemberVersion.__table__.c.user_id.nullable