3 Using Audrius' models from flask browser.
5 This file contains models that are used with SQLAlchemy.
7 Note: some things done in methods written in classes rely on the querying module adding extra information to classes,
8 so these will not work in a normal context outside the framework.
11 from __future__
import print_function
12 from __future__
import absolute_import
18 from sqlalchemy.orm
import relationship, backref
19 from sqlalchemy.ext.declarative
import declarative_base
21 from sqlalchemy
import Column, String, Integer, DateTime, Binary, ForeignKey, BigInteger, and_
23 print(
"You must be working inside a CMSSW environment. Try running 'cmsenv'.")
26 from .
import data_sources, data_formats
27 import urllib, urllib2, base64
28 from copy
import deepcopy
31 from .utils
import to_timestamp, to_datetime, friendly_since
38 if object.__class__.__name__.lower() ==
"payload":
39 map_blobs = object.blobs_mapped
44 cls = object.__class__
46 new_class =
generate(map_blobs=map_blobs, class_name=class_name)
47 new_class.__table__.schema = schema
48 new_object = new_class(object.as_dicts(), convert_timestamps=
False)
53 if isinstance(objects, list):
54 return map(session_independent_object, objects)
60 class_name = cls.__name__
62 for character
in class_name:
63 all_upper_case = character.isupper()
66 for n
in range(0, len(class_name)):
67 if class_name[n].isupper()
and n != 0:
68 class_name =
str(class_name[0:n]) +
"".
join([
"_", class_name[n].lower()]) +
str(class_name[n+1:])
69 elif class_name[n].isupper()
and n == 0:
70 class_name =
str(class_name[0:n]) +
"".
join([class_name[n].lower()]) +
str(class_name[n+1:])
79 return full_status[status]
82 days = radius.get(
"days")
83 days += radius.get(
"weeks")*7
if radius.get(
"weeks") !=
None else 0
84 days += radius.get(
"months")*28
if radius.get(
"months") !=
None else 0
85 days += radius.get(
"years")+365
if radius.get(
"years") !=
None else 0
90 Base class for Radius and Range - used for checking by apply_filter function
104 Used to tell proxy methods that a range of values defined by a centre and a radius should be queried for - special case of filter clauses.
108 centre and radius should be objects that can be added and subtracted.
109 eg, centre could be a datetime.datetime object, and radius could be datetime.timedelta
111 Radius and Range objects are assigned to properties of querying.connection objects, hence are given the database type.
120 Used to tell proxy methods that a range of values defined by a start and end point should be queried for - special case of filter clauses.
124 centre and radius should be objects that can be added and subtracted.
125 eg, centre could be a datetime.datetime object, and radius could be datetime.timedelta
127 Radius and Range objects are assigned to properties of querying.connection objects, hence are given the database type.
134 Used to tell proxy methods that a regular expression should be used to query the column.
145 return sqlalchemy.func.regexp_like(field, regexp)
148 self.connection_object.engine.pool.connect().create_function(
'regexp', 2,
lambda data, regexp: re.search(regexp, data)
is not None)
150 return sqlalchemy.func.regexp(field, regexp)
152 raise NotImplemented(
"Can only apply regular expression search to Oracle, Frontier and SQLite.")
155 filter_attribute = getattr(orm_class, attribute)
156 if isinstance(value, list):
157 orm_query = orm_query.filter(filter_attribute.in_(value))
159 orm_query = orm_query.filter(filter_attribute.in_(value.data()))
160 elif type(value)
in [Range, Radius]:
162 minus = value.get_start()
163 plus = value.get_end()
164 orm_query = orm_query.filter(and_(filter_attribute >= minus, filter_attribute <= plus))
166 elif isinstance(value, RegExp):
170 if value.database_type
in [
"oracle",
"frontier"]:
171 regexp = sqlalchemy.func.regexp_like(filter_attribute, value.get_regexp())
172 elif value.database_type ==
"sqlite":
173 value.connection_object.engine.pool.connect().create_function(
'regexp', 2,
lambda data, regexp: re.search(regexp, data)
is not None)
174 regexp = sqlalchemy.func.regexp(filter_attribute, value.get_regexp())
176 raise NotImplemented(
"Can only apply regular expression search to Oracle, Frontier and SQLite.")
177 orm_query = orm_query.filter(regexp)
180 orm_query = orm_query.filter(filter_attribute == value)
184 for (key, value)
in filters.items():
185 if not(key
in [
"amount"]):
186 orm_query =
apply_filter(orm_query, orm_class, key, value)
191 Base = declarative_base()
194 __tablename__ =
'GLOBAL_TAG'
196 headers = [
"name",
"validity",
"description",
"release",
"insertion_time",
"snapshot_time",
"scenario",
"workflow",
"type"]
198 name = Column(String(100), unique=
True, nullable=
False, primary_key=
True)
199 validity = Column(Integer, nullable=
False)
200 description = Column(String(4000), nullable=
False)
201 release = Column(String(100), nullable=
False)
202 insertion_time = Column(DateTime, nullable=
False)
203 snapshot_time = Column(DateTime, nullable=
False)
204 scenario = Column(String(100))
205 workflow = Column(String(100))
206 type = Column(String(1))
207 tag_map = relationship(
'GlobalTagMap', backref=
'global_tag')
209 def __init__(self, dictionary={}, convert_timestamps=True):
211 for key
in dictionary:
213 if convert_timestamps:
216 self.__dict__[key] = dictionary[key]
217 except KeyError
as k:
221 return '<GlobalTag %r>' % self.name
223 def as_dicts(self, convert_timestamps=False):
225 Returns dictionary form of Global Tag object.
229 'validity': self.validity,
230 'description': self.description,
231 'release': self.release,
232 'insertion_time':
to_timestamp(self.insertion_time)
if convert_timestamps
else self.insertion_time,
233 'snapshot_time':
to_timestamp(self.snapshot_time)
if convert_timestamps
else self.snapshot_time,
234 'scenario': self.scenario,
235 'workflow': self.workflow,
241 return [self.name, self.release,
to_timestamp(self.insertion_time),
to_timestamp(self.snapshot_time), self.description]
243 def all(self, **kwargs):
245 Returns `amount` Global Tags ordered by Global Tag name.
247 query = self.session.
query(GlobalTag)
249 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
250 query_result = query.order_by(GlobalTag.name).
limit(amount).
all()
254 def tags(self, **kwargs):
256 Returns `amount` *Global Tag Maps* belonging to this Global Tag.
258 kwargs[
"global_tag_name"] = self.name
259 all_tags = self.session.
query(GlobalTagMap.global_tag_name, GlobalTagMap.record, GlobalTagMap.label, GlobalTagMap.tag_name)
261 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
262 all_tags = all_tags.order_by(GlobalTagMap.tag_name).
limit(amount).
all()
263 column_names = [
"global_tag_name",
"record",
"label",
"tag_name"]
264 all_tags =
map(
lambda row : dict(
zip(column_names,
map(to_timestamp, row))), all_tags)
268 def iovs(self, **kwargs):
270 Returns `amount` IOVs belonging to all Tags held in this Global Tag.
271 For large Global Tags (which is most of them), VERY slow.
272 Highly recommended to instead used `tags().get_members("tag_name").data()` to get a `list` of tag names,
273 and then get IOVs from each Tag name.
275 At some point, this method may replace the method currently used.
281 tag_names = self.tags().get_members(
"tag_name").
data()
282 iovs_all_tags = self.session.
query(IOV).
filter(IOV.tag_name.in_(tag_names))
284 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
285 iovs_all_tags = iovs_all_tags.limit(amount).subquery()
288 iovs_gt_tags = self.session.
query(GlobalTagMap.tag_name, iovs_all_tags.c.since,\
289 iovs_all_tags.c.payload_hash, iovs_all_tags.c.insertion_time)\
290 .
filter(GlobalTagMap.global_tag_name == self.name)\
291 .
join(iovs_all_tags, GlobalTagMap.tag_name == iovs_all_tags.c.tag_name)
293 iovs_gt_tags = iovs_gt_tags.order_by(iovs_all_tags.c.since).
all()
295 column_names = [
"tag_name",
"since",
"payload_hash",
"insertion_time"]
296 all_iovs =
map(
lambda row : dict(
zip(column_names, row)), iovs_gt_tags)
301 def __sub__(self, other):
303 Allows Global Tag objects to be used with the "-" arithmetic operator to find their difference.
304 Note: gt1 - gt2 = gt1.diff(gt2) ( = gt2 - gt1 = gt2.diff(gt1))
306 return self.diff(other)
310 Returns the json_list of differences in the form of tuples:
312 (record, label, tag name of gt1 (self), tag name of gt2 (gt))
315 record_label_to_tag_name1 = dict([((gt_map.record, gt_map.label), gt_map.tag_name)
for gt_map
in self.tags().
data()])
316 record_label_to_tag_name2 = dict([((gt_map.record, gt_map.label), gt_map.tag_name)
for gt_map
in gt.tags().
data()])
318 record_label_pairs = sorted(set(record_label_to_tag_name1) | set(record_label_to_tag_name2))
321 tags_pairs_with_differences = []
323 for record_label
in record_label_pairs:
324 tag_name1 = record_label_to_tag_name1.get(record_label)
325 tag_name2 = record_label_to_tag_name2.get(record_label)
327 if tag_name1 ==
None or tag_name2 ==
None or tag_name1 != tag_name2:
329 "Record" : record_label[0],
330 "Label" : record_label[1],
331 (
"%s Tag" % self.name) : tag_name1,
332 (
"%s Tag" % gt.name) : tag_name2
337 class GlobalTagMap(
Base):
338 __tablename__ =
'GLOBAL_TAG_MAP'
340 headers = [
"global_tag_name",
"record",
"label",
"tag_name"]
342 global_tag_name = Column(String(100), ForeignKey(
'GLOBAL_TAG.name'), primary_key=
True, nullable=
False)
343 record = Column(String(100), ForeignKey(
'RECORDS.record'), primary_key=
True, nullable=
False)
344 label = Column(String(100), primary_key=
True, nullable=
False)
345 tag_name = Column(String(100), ForeignKey(
'TAG.name'), nullable=
False)
347 def __init__(self, dictionary={}, convert_timestamps=True):
349 for key
in dictionary:
351 if convert_timestamps:
354 self.__dict__[key] = dictionary[key]
355 except KeyError
as k:
359 return '<GlobalTagMap %r>' % self.global_tag_name
361 def as_dicts(self, convert_timestamps=False):
363 Returns dictionary form of this Global Tag Map.
366 "global_tag_name" :
str(self.global_tag_name),
367 "record" :
str(self.record),
368 "label" :
str(self.label),
369 "tag_name" :
str(self.tag_name)
374 class GlobalTagMapRequest(
Base):
375 __tablename__ =
'GLOBAL_TAG_MAP_REQUEST'
377 queue = Column(String(100), primary_key=
True, nullable=
False)
378 tag = Column(String(100), ForeignKey(
'TAG.name'), primary_key=
True, nullable=
False)
379 record = Column(String(100), ForeignKey(
'RECORDS.record'), primary_key=
True, nullable=
False)
380 label = Column(String(100), primary_key=
True, nullable=
False)
381 status = Column(String(1), nullable=
False)
382 description = Column(String(4000), nullable=
False)
383 submitter_id = Column(Integer, nullable=
False)
384 time_submitted = Column(DateTime, nullable=
False)
385 last_edited = Column(DateTime, nullable=
False)
387 def __init__(self, dictionary={}, convert_timestamps=True):
389 for key
in dictionary:
391 if convert_timestamps:
394 self.__dict__[key] = dictionary[key]
395 except KeyError
as k:
398 headers = [
"queue",
"tag",
"record",
"label",
"status",
"description",
"submitter_id",
"time_submitted",
"last_edited"]
402 Returns dictionary form of this Global Tag Map Request.
405 "queue" : self.queue,
407 "record" : self.record,
408 "label" : self.label,
409 "status" : self.status,
410 "description" : self.description,
411 "submitter_id" : self.submitter_id,
412 "time_submitted" : self.time_submitted,
413 "last_edited" : self.last_edited
417 return '<GlobalTagMapRequest %r>' % self.queue
423 __tablename__ =
'IOV'
425 headers = [
"tag_name",
"since",
"payload_hash",
"insertion_time"]
427 tag_name = Column(String(4000), ForeignKey(
'TAG.name'), primary_key=
True, nullable=
False)
428 since = Column(Integer, primary_key=
True, nullable=
False)
429 payload_hash = Column(String(40), ForeignKey(
'PAYLOAD.hash'), nullable=
False)
430 insertion_time = Column(DateTime, primary_key=
True, nullable=
False)
432 def __init__(self, dictionary={}, convert_timestamps=True):
434 for key
in dictionary:
436 if convert_timestamps:
439 self.__dict__[key] = dictionary[key]
440 except KeyError
as k:
443 def as_dicts(self, convert_timestamps=False):
445 Returns dictionary form of this IOV.
448 "tag_name" : self.tag_name,
449 "since" : self.since,
450 "payload_hash" : self.payload_hash,
451 "insertion_time" :
to_timestamp(self.insertion_time)
if convert_timestamps
else self.insertion_time
455 return '<IOV %r>' % self.tag_name
458 return [self.since,
to_timestamp(self.insertion_time), self.payload_hash]
460 def all(self, **kwargs):
462 Returns `amount` IOVs ordered by since.
464 query = self.session.
query(IOV)
466 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
467 query_result = query.order_by(IOV.tag_name).order_by(IOV.since).
limit(amount).
all()
472 __tablename__ =
'PAYLOAD'
474 headers = [
"hash",
"object_type",
"version",
"insertion_time"]
476 hash = Column(String(40), primary_key=
True, nullable=
False)
477 object_type = Column(String(4000), nullable=
False)
478 version = Column(String(4000), nullable=
False)
479 insertion_time = Column(DateTime, nullable=
False)
481 data = Column(Binary, nullable=
False)
482 streamer_info = Column(Binary, nullable=
False)
483 blobs_mapped = map_blobs
485 def __init__(self, dictionary={}, convert_timestamps=True):
487 for key
in dictionary:
489 if convert_timestamps:
492 self.__dict__[key] = dictionary[key]
493 except KeyError
as k:
497 def as_dicts(self, convert_timestamps=False):
499 Returns dictionary form of this Payload's metadata (not the actual Payload).
503 "object_type" : self.object_type,
504 "version" : self.version,
505 "insertion_time" :
to_timestamp(self.insertion_time)
if convert_timestamps
else self.insertion_time,
507 "streamer_info" : self.streamer_info
510 def as_dicts(self, convert_timestamps=False):
512 Returns dictionary form of this Payload's metadata (not the actual Payload).
516 "object_type" : self.object_type,
517 "version" : self.version,
518 "insertion_time" :
to_timestamp(self.insertion_time)
if convert_timestamps
else self.insertion_time
522 return '<Payload %r>' % self.hash
525 return [self.hash, self.object_type, self.version,
to_timestamp(self.insertion_time)]
527 def parent_tags(self, **kwargs):
529 Returns `amount` parent Tags ordered by Tag name.
535 kwargs[
"payload_hash"] = self.hash
536 query = self.session.
query(IOV.tag_name)
538 query_result = query.all()
539 tag_names =
map(
lambda entry : entry[0], query_result)
540 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
541 tags = self.session.
query(Tag).
filter(Tag.name.in_(tag_names)).order_by(Tag.name).
limit(amount).
all()
544 def all(self, **kwargs):
546 Returns `amount` Payloads ordered by Payload hash.
548 query = self.session.
query(Payload)
550 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
551 query_result = query.order_by(Payload.hash).
limit(amount).
all()
556 __tablename__ =
'RECORDS'
558 headers = [
"record",
"object",
"type"]
560 record = Column(String(100), primary_key=
True, nullable=
False)
561 object = Column(String(200), nullable=
False)
562 type = Column(String(20), nullable=
False)
566 Returns dictionary form of this Record.
569 "record" : self.record,
570 "object" : self.object,
575 return '<Record %r>' % self.record
578 return [self.record, self.object]
580 def all(self, **kwargs):
582 Returns `amount` Records ordered by Record record.
584 query = self.session.
query(Record)
586 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
587 query_result = query.order_by(Record.record).
limit(amount).
all()
592 __tablename__ =
'TAG'
594 headers = [
"name",
"time_type",
"object_type",
"synchronization",
"end_of_validity",\
595 "description",
"last_validated_time",
"insertion_time",
"modification_time"]
597 name = Column(String(4000), primary_key=
True, nullable=
False)
598 time_type = Column(String(4000), nullable=
False)
599 object_type = Column(String(4000), nullable=
False)
600 synchronization = Column(String(4000), nullable=
False)
601 end_of_validity = Column(Integer, nullable=
False)
602 description = Column(String(4000), nullable=
False)
603 last_validated_time = Column(BigInteger, nullable=
False)
604 insertion_time = Column(DateTime, nullable=
False)
605 modification_time = Column(DateTime, nullable=
False)
610 iovs_list = relationship(
'IOV', backref=
'tag')
612 def __init__(self, dictionary={}, convert_timestamps=True):
614 for key
in dictionary:
616 if convert_timestamps:
619 self.__dict__[key] = dictionary[key]
620 except KeyError
as k:
623 def as_dicts(self, convert_timestamps=False):
625 Returns dictionary form of this Tag.
629 "time_type" : self.time_type,
630 "object_type" : self.object_type,
631 "synchronization" : self.synchronization,
632 "end_of_validity" : self.end_of_validity,
633 "description" : self.description,
634 "last_validated_time" : self.last_validated_time,
635 "insertion_time" :
to_timestamp(self.insertion_time)
if convert_timestamps
else self.insertion_time,
636 "modification_time" :
to_timestamp(self.modification_time)
if convert_timestamps
else self.modification_time,
637 "record" : self.record,
642 return '<Tag %r>' % self.name
645 return [self.name, self.time_type, self.object_type, self.synchronization,
to_timestamp(self.insertion_time), self.description]
647 def parent_global_tags(self, **kwargs):
649 Returns `amount` Global Tags that contain this Tag.
654 kwargs[
"tag_name"] = self.name
655 query = self.session.
query(GlobalTagMap.global_tag_name)
657 query_result = query.all()
658 if len(query_result) != 0:
659 global_tag_names =
map(
lambda entry : entry[0], query_result)
660 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
661 global_tags = self.session.
query(GlobalTag).
filter(GlobalTag.name.in_(global_tag_names)).order_by(GlobalTag.name).
limit(amount).
all()
666 def all(self, **kwargs):
668 Returns `amount` Tags ordered by Tag name.
670 query = self.session.
query(Tag)
672 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
673 query_result = query.order_by(Tag.name).
limit(amount).
all()
676 def iovs(self, **kwargs):
678 Returns `amount` IOVs that belong to this Tag ordered by IOV since.
681 iovs_query = self.session.
query(IOV).
filter(IOV.tag_name == self.name)
683 amount = kwargs[
"amount"]
if "amount" in kwargs.keys()
else None
684 iovs = iovs_query.order_by(IOV.since).
limit(amount).
all()
687 def latest_iov(self):
689 Returns the single highest since held by this Tag.
690 Insertion times do not matter - if there are two IOVs at since > all others, both have the highest since.
692 iov = self.session.
query(IOV).
filter(IOV.tag_name == self.name).order_by(IOV.since.desc()).
first()
695 def __sub__(self, other):
697 Allows the arithmetic operator "-" to be applied to find the difference between two tags.
698 Note: diff() is symmetric, hence tag1 - tag2 = tag2 - tag1.
700 return self.diff(other)
702 def diff(self, tag, short=False):
704 Returns the `diff` of the first Tag, and the Tag given.
705 Summary of algorithm:
707 Compute the ordered set of iov sinces from both tags, and construct a list of triples, (since, tag1 hash, tag2 hash).
708 Set previous_payload1 and previous_payload2 to be the first hash values from each tag for the first since in the merged list.
709 Note: depending on where each Tag's IOVs start, 1 or both of these values can be None.
710 Set the first_since_in_equality_range = -1, which holds the since at which the last hashes were equal in the Tags.
711 For each triple (since, hash1, hash2),
713 If the first_since_in_equality_range = None,
714 We are at the first since in the merged list, so set first_since... = since
715 Note: this is so set the previous... values for the second row, since the first row will never result in a print because
716 a row is only printed when past iovs have been processed.
718 If either hash1 or hash2 is None, set it to the previous hash found
719 Note: if a Tag defines a hash for one since and then not another for n rows, the last defined hash will be carried through because of this.
721 If the previous found hashes were equal, that means we have equality on the range [first_since_in_equality_range, since)
722 Note: we CANNOT conclude anything about the hashes corresponding to sinces >= since
723 because we have no looked forward, but we do know about the previous hashes.
726 The region of equality has ended, and so we have that [first_since_in_equality_range, since) is equal for both Tags
727 Hence, print that for this range we have equal hashes denoted by "=" in each hash column.
731 The previous hashes were not equal, BUT we must check that ths hashes on this row are not identical...
732 If the hashes on this row are the same as the hashes above (hash1 == previous_payload1 and hash2 == previous_payload2),
733 then we have not found the end of a region of equality!
734 If the hashes have changed, print a row.
737 if tag.__class__.__name__ !=
"Tag":
738 raise TypeError(
"Tag given must be a CondDBFW Tag object.")
741 iovs1 = dict(
map(
lambda iov : (iov.since, iov.payload_hash), self.iovs().
data()))
742 iovs2 = dict(
map(
lambda iov : (iov.since, iov.payload_hash), tag.iovs().
data()))
744 iovs = [(x, iovs1.get(x), iovs2.get(x))
for x
in sorted(set(iovs1) | set(iovs2))]
745 iovs.append((
"Infinity", 1, 2))
748 previous_hash1 =
None
749 previous_hash2 =
None
750 first_since_in_equality_range =
None
751 previous_equal =
False
753 for since, hash1, hash2
in iovs:
755 if first_since_in_equality_range ==
None:
760 first_since_in_equality_range = since
761 previous_hash1 = hash1
762 previous_hash2 = hash2
763 previous_equal = hash1 == hash2
769 hash1 = previous_hash1
771 hash2 = previous_hash2
776 table.append({
"since" :
"[%s, %s)" % (first_since_in_equality_range, since), self.name :
"=", tag.name :
"="})
778 first_since_in_equality_range = since
784 if not(hash1 == previous_hash1
and hash2 == previous_hash2):
785 table.append({
"since" :
"[%s, %s)" % (first_since_in_equality_range, since), self.name : previous_hash1, tag.name : previous_hash2})
786 first_since_in_equality_range = since
788 previous_hash1 = hash1
789 previous_hash2 = hash2
790 previous_equal = hash1 == hash2
795 def merge_into(self, tag, range_object):
797 Given another connection, apply the 'merge' algorithm to merge the IOVs from this Tag
798 into the IOVs of the other Tag.
800 tag : CondDBFW Tag object that the IOVs from this Tag should be merged into.
802 range_object : CondDBFW.data_sources.Range object to describe the subset of IOVs that should be copied
803 from the database this Tag belongs to.
805 Script originally written by Joshua Dawes,
806 and adapted by Giacomo Govi, Gianluca Cerminara and Giovanni Franzoni.
810 merged_tag_name = oracle_tag.name +
"_merged"
813 since_range = range_object
819 if sqlite_tag ==
None:
820 raise TypeError(
"Tag to be merged cannot be None.")
822 sqlite_iovs = sqlite_tag.iovs().
data()
823 sqlite_tag.iovs().as_table()
825 new_tag = self.connection.models[
"tag"](sqlite_tag.as_dicts(convert_timestamps=
False), convert_timestamps=
False)
826 new_tag.name = merged_tag_name
828 imported_iovs = oracle_tag.iovs(since=since_range).
data()
830 for i
in range(0, len(imported_iovs)):
831 imported_iovs[i].source =
"oracle"
833 sqlite_iovs_sinces=[]
834 for i
in range(0, len(sqlite_iovs)):
835 sqlite_iovs[i].source =
"sqlite"
836 sqlite_iovs_sinces.append(sqlite_iovs[i].since)
839 print(sqlite_iovs_sinces)
841 new_iovs_list = imported_iovs + sqlite_iovs
842 new_iovs_list = sorted(new_iovs_list, key=
lambda iov : iov.since)
844 for (n, iov)
in enumerate(new_iovs_list):
846 if iov.source ==
"oracle":
847 if new_iovs_list[n].since
in sqlite_iovs_sinces:
850 iov.source =
"tobedeleted"
854 for i
in reversed(
range(0,n)):
855 if new_iovs_list[i].source ==
"sqlite":
856 print(
"change %s to %s at since %d" % (iov.payload_hash, new_iovs_list[i].payload_hash, iov.since))
857 iov.payload_hash = new_iovs_list[i].payload_hash
861 new_iov_list_copied = []
863 for iov
in new_iovs_list:
865 if iov.source !=
"tobedeleted":
866 new_iov_list_copied.append(iov)
868 new_iov_list_copied = sorted(new_iov_list_copied, key=
lambda iov : iov.since)
870 now = datetime.datetime.now()
873 for iov
in new_iov_list_copied:
874 new_iovs.append( self.connection.models[
"iov"](iov.as_dicts(convert_timestamps=
False), convert_timestamps=
False) )
876 iov.insertion_time = now
877 iov.tag_name = merged_tag_name
879 new_tag.iovs_list = new_iovs
884 classes = {
"globaltag" : GlobalTag,
"iov" : IOV,
"globaltagmap" : GlobalTagMap,\
885 "payload" : Payload,
"tag" : Tag,
"Base" : Base}
887 if class_name ==
None:
890 return classes[class_name]