CMS 3D CMS Logo

conddblib.py
Go to the documentation of this file.
1 '''CMS Conditions DB Python library.
2 '''
3 
4 __author__ = 'Miguel Ojeda'
5 __copyright__ = 'Copyright 2013, CERN'
6 __credits__ = ['Giacomo Govi', 'Miguel Ojeda', 'Andreas Pfeiffer']
7 __license__ = 'Unknown'
8 __maintainer__ = 'Giacomo Govi'
9 __email__ = 'mojedasa@cern.ch'
10 
11 
12 import os
13 import hashlib
14 import logging
15 
16 import sqlalchemy
17 import sqlalchemy.ext.declarative
18 
19 authPathEnvVar = 'COND_AUTH_PATH'
20 schema_name = 'CMS_CONDITIONS'
21 dbuser_name = 'cms_conditions'
22 dbreader_user_name = 'cms_cond_general_r'
23 dbwriter_user_name = 'cms_cond_general_w'
24 devdbwriter_user_name = 'cms_cond_general_w'
25 logger = logging.getLogger(__name__)
26 
27 # frontier services
28 PRO ='PromptProd'
29 ARC ='FrontierArc'
30 INT ='FrontierInt'
31 DEV ='FrontierPrep'
32 # oracle read only services
33 ORAPRO = 'cms_orcon_adg'
34 ORAARC = 'cmsarc_lb'
35 # oracle masters
36 ORAINT = 'cms_orcoff_int'
37 ORADEV = 'cms_orcoff_prep'
38 ONLINEORAPRO = 'cms_orcon_prod'
39 ONLINEORAINT = 'cmsintr_lb'
40 
41 # Set initial level to WARN. This so that log statements don't occur in
42 # the absense of explicit logging being enabled.
43 if logger.level == logging.NOTSET:
44  logger.setLevel(logging.WARN)
45 
46 
47 class EnumMetaclass(type):
48  def __init__(cls, name, bases, dct):
49  cls._members = sorted([member for member in dir(cls) if not member.startswith('_')])
50  cls._map = dict([(member, getattr(cls, member)) for member in cls._members])
51  cls._reversemap = dict([(value, key) for (key, value) in cls._map.items()])
52  super(EnumMetaclass, cls).__init__(name, bases, dct)
53 
54  def __len__(cls):
55  return len(cls._members)
56 
57  def __getitem__(cls, key):
58  '''Returns the value for this key (if the key is an integer,
59  the value is the nth member from the sorted members list).
60  '''
61 
62  if isinstance(key, int):
63  # for tuple() and list()
64  key = cls._members[key]
65  return cls._map[key]
66 
67  def __call__(cls, value):
68  '''Returns the key for this value.
69  '''
70 
71  return cls._reversemap[value]
72 
73 
74 class Enum(object):
75  '''A la PEP 435, simplified.
76  '''
77 
78  __metaclass__ = EnumMetaclass
79 
80 
81 # Utility functions
82 def hash(data):
83  return hashlib.sha1(data).hexdigest()
84 
85 
86 # Constants
87 empty_label = '-'
88 
89 name_length = 100
90 description_length = 4000
91 hash_length = len(hash(''))
92 
93 web_experts_email = 'cms-cond-dev@cern.ch'
94 offline_db_experts_email = 'cms-offlinedb-exp@cern.ch'
95 offline_db_experts_phone = '+41 22 76 70817, or 70817 from CERN; check https://twiki.cern.ch/twiki/bin/viewauth/CMS/DBShifterHelpPage if it does not work; availability depends on the state of the LHC'
96 
97 contact_help = 'If you need assistance, please write an email to %s and %s. If you need immediate/urgent assistance, you can call the Offline DB expert on call (%s).' % (offline_db_experts_email, web_experts_email, offline_db_experts_phone)
98 database_help = '''
99  The database parameter (--db) refers to the database where the tool
100  will connect to read all the data. By default, the production account
101  (through Frontier) will be used.
102 
103  In subcommands which take a source and a destination, --db always refers to
104  the source, and --destdb to the destination. For both of them the following
105  rules apply.
106 
107  The database parameter can be an official alias, a filename or any
108  valid SQLAlchemy URL.
109 
110  The official aliases are the following strings (first column):
111 
112  Alias Level Database RO/RW Notes
113  ------------ ----------- ------------- ---------- -------------------------------
114 
115  pro Production Frontier (ADG) read-only Default.
116  arc Archive Frontier read-only
117  int Integration Frontier read-only
118  dev Development Frontier read-only
119  boost Production Frontier read-only
120  boostprep Development Frontier read-only
121 
122  orapro Production Oracle (ADG) read-only Password required.
123  oraarc Archive Oracle read-only Password required.
124  oraint Integration Oracle read-write Password required.
125  oradev Development Oracle read-write Password required.
126 
127  onlineorapro Production Oracle read-write Password required. Online only.
128  onlineoraint Online Int Oracle read-write Password required. Online only.
129 
130  Most of the time, if you are a regular user, you will want to read/copy
131  conditions from the Frontier production account. Therefore, you can omit
132  the --db parameter, unless you want to read from somewhere else,
133  e.g. from your local SQLite file.
134 
135  In addition, the parameter may be a filename (path) pointing to a local
136  SQLite file, e.g.
137 
138  file.db
139  relative/path/to/file.db
140  /absolute/path/to/file.db
141 
142  Finally, any valid SQLAlchemy URL can be used. This allows full
143  flexibility in cases where it may be needed, e.g.
144 
145  sqlite:// In-memory, volatile SQLite DB.
146  oracle://user@devdb11 Your private Oracle DB in devdb11 [*]
147 
148  [*] See https://account.cern.ch/ -> Services for more information
149  on personal Oracle accounts.
150 
151  For the official aliases, the password will be asked automatically
152  interactively. The same applies for Oracle URLs where the password
153  was not provided inside it, e.g.:
154 
155  oracle://user@devdb11 The tool will prompt you for the password.
156  oracle://user:pass@devdb11 Password inlined. [+]
157 
158  [+] Caution: Never write passwords in command-line parameters in
159  multi-user machines (e.g. lxplus), since other users can see them
160  in the process table (e.g. ps).
161 
162  This means that both the official aliases and the filenames are shortcuts
163  to the full SQLAlchemy URL equivalents, e.g. the following are the same:
164 
165  relative/path/to/file.db === sqlite:///relative/path/to/file.db
166  /absolute/path/to/file.db === sqlite:////absolute/path/to/file.db
167 '''
168 
170  any = 'any'
171  validation = 'validation'
172  mc = 'mc'
173  runmc = 'runmc'
174  hlt = 'hlt'
175  express = 'express'
176  prompt = 'prompt'
177  pcl = 'pcl'
178  offline = 'offline'
179 
180 class TimeType(Enum):
181  run = 'Run'
182  time = 'Time'
183  lumi = 'Lumi'
184  hash = 'Hash'
185  user = 'User'
186 
187 
188 # Schema definition
189 _Base = sqlalchemy.ext.declarative.declarative_base()
190 
191 def fq_name( schema_name, table_name ):
192  name = table_name
193  if schema_name is not None:
194  name = '%s.%s' %(schema_name, table_name)
195  return name
196 
197 db_models = {}
198 
199 class _Col(Enum):
200  nullable = 0
201  notNull = 1
202  pk = 2
203 
204 class DbRef:
205  def __init__(self,refType, refColumn):
206  self.rtype = refType
207  self.rcol = refColumn
208 
209 def fq_col( schema, table, column ):
210  fqn = '%s.%s' %(table, column)
211  if schema is not None:
212  fqn = '%s.%s' %(schema,fqn)
213  return fqn
214 
215 def make_dbtype( backendName, schemaName, baseType ):
216  members = {}
217  deps_reg = set()
218  dbtype_name = '%s_%s' %(baseType.__name__,backendName)
219  members['__tablename__'] = baseType.__tablename__
220  members['__table_args__'] = None
221  if schemaName is not None:
222  members['__table_args__'] = {'schema': schemaName }
223  for k,v in baseType.columns.items():
224  if isinstance(v[0],DbRef):
225  refColDbt = v[0].rtype.columns[v[0].rcol][0]
226  pk = (True if v[1]==_Col.pk else False)
227  if v[1]==_Col.pk:
228  members[k] = sqlalchemy.Column(refColDbt,sqlalchemy.ForeignKey(fq_col(schemaName,v[0].rtype.__tablename__,v[0].rcol)),primary_key=True)
229  else:
230  nullable = (False if v[1] == _Col.notNull else True)
231  members[k] = sqlalchemy.Column(refColDbt,sqlalchemy.ForeignKey(fq_col(schemaName,v[0].rtype.__tablename__,v[0].rcol)),nullable=nullable)
232  if v[0].rtype.__name__ not in deps_reg:
233  deps_reg.add(v[0].rtype.__name__)
234  reftype_name = '%s_%s' %(v[0].rtype.__name__,backendName)
235  members[(v[0].rtype.__name__).lower()] = sqlalchemy.orm.relationship(reftype_name)
236  else:
237  if v[1]==_Col.pk:
238  members[k] = sqlalchemy.Column(v[0],primary_key=True)
239  else:
240  nullable = (True if v[1]==_Col.nullable else False)
241  members[k] = sqlalchemy.Column(v[0],nullable=nullable)
242  dbType = type(dbtype_name,(_Base,),members)
243 
244  if backendName not in db_models.keys():
245  db_models[backendName] = {}
246  db_models[backendName][baseType.__name__] = dbType
247  return dbType
248 
249 def getSchema(tp):
250  if tp.__table_args__ is not None:
251  return tp.__table_args__['schema']
252  return None
253 
254 class Tag:
255  __tablename__ = 'TAG'
256  columns = { 'name': (sqlalchemy.String(name_length),_Col.pk),
257  'time_type': (sqlalchemy.Enum(*tuple(TimeType)),_Col.notNull),
258  'object_type': (sqlalchemy.String(name_length),_Col.notNull),
259  'synchronization': (sqlalchemy.Enum(*tuple(Synchronization)),_Col.notNull),
260  'description': (sqlalchemy.String(description_length),_Col.notNull),
261  'last_validated_time':(sqlalchemy.BIGINT,_Col.notNull),
262  'end_of_validity':(sqlalchemy.BIGINT,_Col.notNull),
263  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
264  'modification_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
265 
267  __tablename__ = 'TAG_METADATA'
268  columns = { 'tag_name': (DbRef(Tag,'name'),_Col.pk),
269  'min_serialization_v': (sqlalchemy.String(20),_Col.notNull),
270  'modification_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
271 
272 class Payload:
273  __tablename__ = 'PAYLOAD'
274  columns = { 'hash': (sqlalchemy.CHAR(hash_length),_Col.pk),
275  'object_type': (sqlalchemy.String(name_length),_Col.notNull),
276  'data': (sqlalchemy.BLOB,_Col.notNull),
277  'streamer_info':(sqlalchemy.BLOB,_Col.notNull),
278  'version':(sqlalchemy.String(20),_Col.notNull),
279  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
280 
281 
282 class IOV:
283  __tablename__ = 'IOV'
284  columns = { 'tag_name':(DbRef(Tag,'name'),_Col.pk),
285  'since':(sqlalchemy.BIGINT,_Col.pk),
286  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.pk),
287  'payload_hash':(DbRef(Payload,'hash'),_Col.notNull) }
288 
289 
290 class GlobalTag:
291  __tablename__ = 'GLOBAL_TAG'
292  columns = { 'name':(sqlalchemy.String(name_length),_Col.pk),
293  'validity': (sqlalchemy.BIGINT,_Col.notNull),
294  'description':(sqlalchemy.String(description_length),_Col.notNull),
295  'release':(sqlalchemy.String(name_length),_Col.notNull),
296  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
297  'snapshot_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
298 
300  __tablename__ = 'GLOBAL_TAG_MAP'
301  columns = { 'global_tag_name':(DbRef(GlobalTag,'name'),_Col.pk),
302  'record':(sqlalchemy.String(name_length),_Col.pk),
303  'label':(sqlalchemy.String(name_length),_Col.pk),
304  'tag_name':(DbRef(Tag,'name'),_Col.notNull) }
305 
306 
307 
308 class TagLog:
309  __tablename__ = 'TAG_LOG'
310  columns = { 'tag_name':(DbRef(Tag,'name'),_Col.pk),
311  'event_time':(sqlalchemy.TIMESTAMP,_Col.pk),
312  'action':(sqlalchemy.String(100),_Col.pk),
313  'user_name':(sqlalchemy.String(100),_Col.notNull),
314  'host_name':(sqlalchemy.String(100),_Col.notNull),
315  'command':(sqlalchemy.String(500),_Col.notNull),
316  'user_text':(sqlalchemy.String(4000),_Col.notNull) }
317 
318 class RunInfo:
319  __tablename__ = 'RUN_INFO'
320  columns = { 'run_number':(sqlalchemy.BIGINT,_Col.pk),
321  'start_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
322  'end_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
323 
325  __tablename__ = 'BOOST_RUN_MAP'
326  columns = { 'run_number':(sqlalchemy.BIGINT,_Col.pk),
327  'run_start_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
328  'boost_version': (sqlalchemy.String(20),_Col.notNull) }
329 
330 # CondDB object
332 
333  def __init__(self, url):
334  # Workaround to avoid creating files if not present.
335  # Python's sqlite3 module does not use sqlite3_open_v2(),
336  # and therefore we cannot disable SQLITE_OPEN_CREATE.
337  # Only in the case of creating a new database we skip the check.
338  if url.drivername == 'sqlite':
339 
340  self.engine = sqlalchemy.create_engine(url)
341 
342  enabled_foreign_keys = self.engine.execute('pragma foreign_keys').scalar()
343  supports_foreign_keys = enabled_foreign_keys is not None
344  if not supports_foreign_keys:
345  logger.warning('Your SQLite database does not support foreign keys, so constraints will not be checked. Please upgrade.')
346  elif not enabled_foreign_keys:
347  self.engine.execute('pragma foreign_keys = on')
348 
349  else:
350  self.engine = sqlalchemy.create_engine(url)
351 
352  self._session = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(bind=self.engine))
353 
354  self._is_frontier = url.drivername == 'oracle+frontier'
355  self._is_oracle = url.drivername == 'oracle'
356  self._is_sqlite = url.drivername == 'sqlite'
357 
358  self._is_read_only = self._is_frontier or url.host in {
359  'cms_orcon_adg',
360  'cmsarc_lb',
361  }
362 
363  self._is_official = self._is_frontier or url.host in {
364  'cms_orcon_adg',
365  'cmsarc_lb',
366  'cms_orcoff_int',
367  'cms_orcoff_prep',
368  'cms_orcon_prod',
369  'cmsintr_lb',
370  }
371  self._url = url
372  self._backendName = ('sqlite' if self._is_sqlite else 'oracle' )
373  self._schemaName = ( None if self._is_sqlite else schema_name )
374  logging.debug(' ... using db "%s", schema "%s"' % (url, self._schemaName) )
375  logging.debug('Loading db types...')
376  self.get_dbtype(Tag).__name__
377  self.get_dbtype(Payload)
378  self.get_dbtype(IOV)
379  self.get_dbtype(TagLog)
380  self.get_dbtype(GlobalTag)
381  self.get_dbtype(GlobalTagMap)
382  self.get_dbtype(RunInfo)
383  if not self._is_sqlite:
384  self.get_dbtype(TagMetadata)
385  self.get_dbtype(BoostRunMap)
386  self._is_valid = self.is_valid()
387 
388  def get_dbtype(self,theType):
389  basename = theType.__name__
390  if self._backendName not in db_models.keys() or basename not in db_models[self._backendName].keys():
391  return make_dbtype( self._backendName, self._schemaName, theType )
392  else:
393  return db_models[self._backendName][basename]
394 
395  def session(self):
396  s = self._session()
397  s.get_dbtype = self.get_dbtype
398  s._is_sqlite = self._is_sqlite
399  s.is_oracle = self.is_oracle
400  s._url = self._url
401  return s
402 
403  @property
404  def metadata(self):
405  return _Base.metadata
406 
407  @property
408  def is_frontier(self):
409  return self._is_frontier
410 
411  @property
412  def is_oracle(self):
413  return self._is_oracle
414 
415  @property
416  def is_sqlite(self):
417  return self._is_sqlite
418 
419  @property
420  def is_read_only(self):
421  return self._is_read_only
422 
423  @property
424  def is_official(self):
425  return self._is_official
426 
427  def is_valid(self):
428  '''Tests whether the current DB looks like a valid CMS Conditions one.
429  '''
430  engine_connection = self.engine.connect()
431  # temporarely avoid the check on the GT tables - there are releases in use where C++ does not create these tables.
432  _Tag = self.get_dbtype(Tag)
433  _IOV = self.get_dbtype(IOV)
434  _Payload = self.get_dbtype(Payload)
435  ret = all([self.engine.dialect.has_table(engine_connection, table.__tablename__,getSchema(table)) for table in [_Tag, _IOV, _Payload]])
436  engine_connection.close()
437  return ret
438 
439  def init(self, drop=False):
440  '''Initializes a database.
441  '''
442  logging.info('Initializing database...')
443  if drop:
444  logging.debug('Dropping tables...')
445  self.metadata.drop_all(self.engine)
446  self._is_valid = False
447  else:
448  if not self._is_valid:
449  logging.debug('Creating tables...')
450  self.get_dbtype(Tag).__table__.create(bind = self.engine)
451  self.get_dbtype(Payload).__table__.create(bind = self.engine)
452  self.get_dbtype(IOV).__table__.create(bind = self.engine)
453  self.get_dbtype(TagLog).__table__.create(bind = self.engine)
454  self.get_dbtype(GlobalTag).__table__.create(bind = self.engine)
455  self.get_dbtype(GlobalTagMap).__table__.create(bind = self.engine)
456  self._is_valid = True
457 
458 def getSessionOnMasterDB( session1, session2 ):
459  key = '%s/%s'
460  sessiondict = { }
461  sessiondict[key %(session1._url.drivername,session1._url.host)] = session1
462  sessiondict[key %(session2._url.drivername,session2._url.host)] = session2
463  masterkey = key %('oracle',ONLINEORAPRO)
464  if masterkey in sessiondict.keys():
465  return sessiondict[masterkey]
466  adgkey = key %('oracle',ORAPRO)
467  if adgkey in sessiondict.keys():
468  return sessiondict[adgkey]
469  frontierkey = key %('frontier',PRO)
470  if frontierkey in sessiondict.keys():
471  return sessiondict[frontierkey]
472  # default case: frontier on pro
473  conn = Connection(make_url())
474  session = conn.session()
475  # is it required?
476  session._conn = conn
477  return session
478 
479 # Connection helpers
481  import subprocess
482  return subprocess.Popen(['cmsGetFnConnect', 'frontier://%s' % database], stdout = subprocess.PIPE).communicate()[0].strip()
483 
484 def _getCMSSQLAlchemyConnectionString(technology,service,schema_name):
485  if technology == 'frontier':
486  import urllib
487  return '%s://@%s/%s' % ('oracle+frontier', urllib.quote_plus(_getCMSFrontierConnectionString(service)), schema_name )
488  elif technology == 'oracle':
489  return '%s://%s@%s' % (technology, schema_name, service)
490 
491 # Entry point
492 def make_url(database='pro',read_only = True):
493  if database.startswith('sqlite:') or database.startswith('sqlite_file:'):
494  ignore, database = database.split(':',1)
495 
496  if ':' in database and '://' not in database: # check if we really got a shortcut like "pro:<schema>" (and not a url like proto://...), if so, disentangle
497  database, schema = database.split(':')
498 
499  officialdbs = {
500  # frontier
501  'pro' : ('frontier','PromptProd', { 'R': schema_name }, ),
502  'arc' : ('frontier','FrontierArc', { 'R': schema_name }, ),
503  'int' : ('frontier','FrontierInt', { 'R': schema_name }, ),
504  'dev' : ('frontier','FrontierPrep', { 'R': schema_name }, ),
505  # oracle adg
506  'orapro': ('oracle', 'cms_orcon_adg', { 'R': dbreader_user_name }, ),
507  'oraarc': ('oracle', 'cmsarc_lb', { 'R': dbreader_user_name }, ),
508  # oracle masters
509  'oraint': ('oracle', 'cms_orcoff_int', { 'R': dbreader_user_name,
510  'W': dbwriter_user_name }, ),
511  'oradev': ('oracle', 'cms_orcoff_prep', { 'R': dbreader_user_name,
512  'W': devdbwriter_user_name }, ),
513  'onlineorapro': ('oracle', 'cms_orcon_prod', { 'R': dbreader_user_name,
514  'W': dbwriter_user_name }, ),
515  'onlineoraint': ('oracle', 'cmsintr_lb', { 'R': dbreader_user_name,
516  'W': dbwriter_user_name }, ),
517  }
518 
519  if database in officialdbs.keys():
520  key = ('R' if read_only else 'W')
521  mapping = officialdbs[database]
522  tech = mapping[0]
523  service = mapping[1]
524  schema_dict = mapping[2]
525  if key in schema_dict.keys():
526  database = _getCMSSQLAlchemyConnectionString(tech,service,schema_dict[key])
527  else:
528  raise Exception("Read-only database %s://%s cannot be accessed in update mode." %(tech,service))
529 
530  logging.debug('connection string set to "%s"' % database)
531 
532  try:
533  url = sqlalchemy.engine.url.make_url(database)
534  except sqlalchemy.exc.ArgumentError:
535  url = sqlalchemy.engine.url.make_url('sqlite:///%s' % database)
536  return url
537 
538 def connect(url, authPath=None, verbose=0):
539  '''Returns a Connection instance to the CMS Condition DB.
540 
541  See database_help for the description of the database parameter.
542 
543  The verbosity level is as follows:
544 
545  0 = No output (default).
546  1 = SQL statements issued, including their parameters.
547  2 = In addition, results of the queries (all rows and the column headers).
548  '''
549 
550  if url.drivername == 'oracle':
551  if url.username is None:
552  logging.error('Could not resolve the username for the connection %s. Please provide a connection in the format oracle://[user]:[pass]@[host]' %url )
553  raise Exception('Connection format error: %s' %url )
554  if url.password is None:
555  if authPath is None:
556  if authPathEnvVar in os.environ:
557  authPath = os.environ[authPathEnvVar]
558  authFile = None
559  if authPath is not None:
560  authFile = os.path.join(authPath,'.netrc')
561  if authFile is not None:
562  entryKey = url.host.lower()+"/"+url.username.lower()
563  logging.debug('Looking up credentials for %s in file %s ' %(entryKey,authFile) )
564  import netrc
565  params = netrc.netrc( authFile ).authenticators(entryKey)
566  if params is not None:
567  (username, account, password) = params
568  url.password = password
569  else:
570  msg = 'The entry %s has not been found in the .netrc file.' %entryKey
571  raise TypeError(msg)
572  else:
573  import getpass
574  pwd = getpass.getpass('Password for %s: ' % str(url))
575  if pwd is None or pwd == '':
576  pwd = getpass.getpass('Password for %s: ' % str(url))
577  if pwd is None or pwd == '':
578  raise Exception('Empty password provided, bailing out...')
579  url.password = pwd
580 
581  if verbose >= 1:
582  logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
583 
584  if verbose >= 2:
585  logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
586 
587  return Connection(url)
588 
589 
590 def _exists(session, primary_key, value):
591  ret = None
592  try:
593  ret = session.query(primary_key).\
594  filter(primary_key == value).\
595  count() != 0
596  except sqlalchemy.exc.OperationalError:
597  pass
598 
599  return ret
600 
601 def _inserted_before(timestamp):
602  '''To be used inside filter().
603  '''
604 
605  if timestamp is None:
606  # XXX: Returning None does not get optimized (skipped) by SQLAlchemy,
607  # and returning True does not work in Oracle (generates "and 1"
608  # which breaks Oracle but not SQLite). For the moment just use
609  # this dummy condition.
610  return sqlalchemy.literal(True) == sqlalchemy.literal(True)
611 
612  return conddb.IOV.insertion_time <= _parse_timestamp(timestamp)
613 
614 def listObject(session, name, snapshot=None):
615 
616  is_tag = _exists(session, Tag.name, name)
617  result = {}
618  if is_tag:
619  result['type'] = 'Tag'
620  result['name'] = session.query(Tag).get(name).name
621  result['timeType'] = session.query(Tag.time_type).\
622  filter(Tag.name == name).\
623  scalar()
624 
625  result['iovs'] = session.query(IOV.since, IOV.insertion_time, IOV.payload_hash, Payload.object_type).\
626  join(IOV.payload).\
627  filter(
628  IOV.tag_name == name,
629  _inserted_before(snapshot),
630  ).\
631  order_by(IOV.since.desc(), IOV.insertion_time.desc()).\
632  from_self().\
633  order_by(IOV.since, IOV.insertion_time).\
634  all()
635 
636  try:
637  is_global_tag = _exists(session, GlobalTag.name, name)
638  if is_global_tag:
639  result['type'] = 'GlobalTag'
640  result['name'] = session.query(GlobalTag).get(name)
641  result['tags'] = session.query(GlobalTagMap.record, GlobalTagMap.label, GlobalTagMap.tag_name).\
642  filter(GlobalTagMap.global_tag_name == name).\
643  order_by(GlobalTagMap.record, GlobalTagMap.label).\
644  all()
645  except sqlalchemy.exc.OperationalError:
646  sys.stderr.write("No table for GlobalTags found in DB.\n\n")
647 
648  if not is_tag and not is_global_tag:
649  raise Exception('There is no tag or global tag named %s in the database.' % name)
650 
651  return result
652 
653 def getPayload(session, hash):
654  # get payload from DB:
655  data, payloadType = session.query(Payload.data, Payload.object_type).filter(Payload.hash == hash).one()
656  return data
def __getitem__(cls, key)
Definition: conddblib.py:57
def init(self, drop=False)
Definition: conddblib.py:439
def listObject(session, name, snapshot=None)
Definition: conddblib.py:614
def getPayload(session, hash)
Definition: conddblib.py:653
def is_valid(self)
Definition: conddblib.py:427
def metadata(self)
Definition: conddblib.py:404
def getSessionOnMasterDB(session1, session2)
Definition: conddblib.py:458
def is_oracle(self)
Definition: conddblib.py:412
def __init__(self, url)
Definition: conddblib.py:333
def _getCMSFrontierConnectionString(database)
Definition: conddblib.py:480
def is_sqlite(self)
Definition: conddblib.py:416
static void * communicate(void *obj)
Definition: DQMNet.cc:1251
def make_url(database='pro', read_only=True)
Definition: conddblib.py:492
def is_read_only(self)
Definition: conddblib.py:420
def make_dbtype(backendName, schemaName, baseType)
Definition: conddblib.py:215
def is_frontier(self)
Definition: conddblib.py:408
def fq_col(schema, table, column)
Definition: conddblib.py:209
def hash(data)
Definition: conddblib.py:82
def fq_name(schema_name, table_name)
Definition: conddblib.py:191
def getSchema(tp)
Definition: conddblib.py:249
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def __init__(cls, name, bases, dct)
Definition: conddblib.py:48
def connect(url, authPath=None, verbose=0)
Definition: conddblib.py:538
def __call__(cls, value)
Definition: conddblib.py:67
def _getCMSSQLAlchemyConnectionString(technology, service, schema_name)
Definition: conddblib.py:484
def get_dbtype(self, theType)
Definition: conddblib.py:388
dbl *** dir
Definition: mlp_gen.cc:35
def is_official(self)
Definition: conddblib.py:424
def _inserted_before(timestamp)
Definition: conddblib.py:601
def __init__(self, refType, refColumn)
Definition: conddblib.py:205
T get(const Candidate &c)
Definition: component.h:55
def _exists(session, primary_key, value)
Definition: conddblib.py:590
double scalar(const CLHEP::HepGenMatrix &m)
Return the matrix as a scalar. Raise an assertion if the matris is not .
Definition: matutil.cc:183