CMS 3D CMS Logo

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