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  'min_since': (sqlalchemy.BIGINT,_Col.notNull),
271  'modification_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
272 
273 class Payload:
274  __tablename__ = 'PAYLOAD'
275  columns = { 'hash': (sqlalchemy.CHAR(hash_length),_Col.pk),
276  'object_type': (sqlalchemy.String(name_length),_Col.notNull),
277  'data': (sqlalchemy.BLOB,_Col.notNull),
278  'streamer_info':(sqlalchemy.BLOB,_Col.notNull),
279  'version':(sqlalchemy.String(20),_Col.notNull),
280  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
281 
282 
283 class IOV:
284  __tablename__ = 'IOV'
285  columns = { 'tag_name':(DbRef(Tag,'name'),_Col.pk),
286  'since':(sqlalchemy.BIGINT,_Col.pk),
287  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.pk),
288  'payload_hash':(DbRef(Payload,'hash'),_Col.notNull) }
289 
290 
291 class GlobalTag:
292  __tablename__ = 'GLOBAL_TAG'
293  columns = { 'name':(sqlalchemy.String(name_length),_Col.pk),
294  'validity': (sqlalchemy.BIGINT,_Col.notNull),
295  'description':(sqlalchemy.String(description_length),_Col.notNull),
296  'release':(sqlalchemy.String(name_length),_Col.notNull),
297  'insertion_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
298  'snapshot_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
299 
301  __tablename__ = 'GLOBAL_TAG_MAP'
302  columns = { 'global_tag_name':(DbRef(GlobalTag,'name'),_Col.pk),
303  'record':(sqlalchemy.String(name_length),_Col.pk),
304  'label':(sqlalchemy.String(name_length),_Col.pk),
305  'tag_name':(DbRef(Tag,'name'),_Col.notNull) }
306 
307 
308 
309 class TagLog:
310  __tablename__ = 'TAG_LOG'
311  columns = { 'tag_name':(DbRef(Tag,'name'),_Col.pk),
312  'event_time':(sqlalchemy.TIMESTAMP,_Col.pk),
313  'action':(sqlalchemy.String(100),_Col.pk),
314  'user_name':(sqlalchemy.String(100),_Col.notNull),
315  'host_name':(sqlalchemy.String(100),_Col.notNull),
316  'command':(sqlalchemy.String(500),_Col.notNull),
317  'user_text':(sqlalchemy.String(4000),_Col.notNull) }
318 
319 class RunInfo:
320  __tablename__ = 'RUN_INFO'
321  columns = { 'run_number':(sqlalchemy.BIGINT,_Col.pk),
322  'start_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
323  'end_time':(sqlalchemy.TIMESTAMP,_Col.notNull) }
324 
326  __tablename__ = 'BOOST_RUN_MAP'
327  columns = { 'run_number':(sqlalchemy.BIGINT,_Col.pk),
328  'run_start_time':(sqlalchemy.TIMESTAMP,_Col.notNull),
329  'boost_version': (sqlalchemy.String(20),_Col.notNull) }
330 
331 # CondDB object
333 
334  def __init__(self, url):
335  # Workaround to avoid creating files if not present.
336  # Python's sqlite3 module does not use sqlite3_open_v2(),
337  # and therefore we cannot disable SQLITE_OPEN_CREATE.
338  # Only in the case of creating a new database we skip the check.
339  if url.drivername == 'sqlite':
340 
341  self.engine = sqlalchemy.create_engine(url)
342 
343  enabled_foreign_keys = self.engine.execute('pragma foreign_keys').scalar()
344  supports_foreign_keys = enabled_foreign_keys is not None
345  if not supports_foreign_keys:
346  logger.warning('Your SQLite database does not support foreign keys, so constraints will not be checked. Please upgrade.')
347  elif not enabled_foreign_keys:
348  self.engine.execute('pragma foreign_keys = on')
349 
350  else:
351  self.engine = sqlalchemy.create_engine(url)
352 
353  self._session = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(bind=self.engine))
354 
355  self._is_frontier = url.drivername == 'oracle+frontier'
356  self._is_oracle = url.drivername == 'oracle'
357  self._is_sqlite = url.drivername == 'sqlite'
358 
359  self._is_read_only = self._is_frontier or url.host in {
360  'cms_orcon_adg',
361  'cmsarc_lb',
362  }
363 
364  self._is_official = self._is_frontier or url.host in {
365  'cms_orcon_adg',
366  'cmsarc_lb',
367  'cms_orcoff_int',
368  'cms_orcoff_prep',
369  'cms_orcon_prod',
370  'cmsintr_lb',
371  }
372  self._url = url
373  self._backendName = ('sqlite' if self._is_sqlite else 'oracle' )
374  self._schemaName = ( None if self._is_sqlite else schema_name )
375  logging.debug(' ... using db "%s", schema "%s"' % (url, self._schemaName) )
376  logging.debug('Loading db types...')
377  self.get_dbtype(Tag).__name__
378  self.get_dbtype(Payload)
379  self.get_dbtype(IOV)
380  self.get_dbtype(TagLog)
381  self.get_dbtype(GlobalTag)
382  self.get_dbtype(GlobalTagMap)
383  self.get_dbtype(RunInfo)
384  if not self._is_sqlite:
385  self.get_dbtype(TagMetadata)
386  self.get_dbtype(BoostRunMap)
387  self._is_valid = self.is_valid()
388 
389  def get_dbtype(self,theType):
390  basename = theType.__name__
391  if self._backendName not in db_models.keys() or basename not in db_models[self._backendName].keys():
392  return make_dbtype( self._backendName, self._schemaName, theType )
393  else:
394  return db_models[self._backendName][basename]
395 
396  def session(self):
397  s = self._session()
398  s.get_dbtype = self.get_dbtype
399  s._is_sqlite = self._is_sqlite
400  s.is_oracle = self.is_oracle
401  s._url = self._url
402  return s
403 
404  @property
405  def metadata(self):
406  return _Base.metadata
407 
408  @property
409  def is_frontier(self):
410  return self._is_frontier
411 
412  @property
413  def is_oracle(self):
414  return self._is_oracle
415 
416  @property
417  def is_sqlite(self):
418  return self._is_sqlite
419 
420  @property
421  def is_read_only(self):
422  return self._is_read_only
423 
424  @property
425  def is_official(self):
426  return self._is_official
427 
428  def is_valid(self):
429  '''Tests whether the current DB looks like a valid CMS Conditions one.
430  '''
431  engine_connection = self.engine.connect()
432  # temporarely avoid the check on the GT tables - there are releases in use where C++ does not create these tables.
433  _Tag = self.get_dbtype(Tag)
434  _IOV = self.get_dbtype(IOV)
435  _Payload = self.get_dbtype(Payload)
436  ret = all([self.engine.dialect.has_table(engine_connection, table.__tablename__,getSchema(table)) for table in [_Tag, _IOV, _Payload]])
437  engine_connection.close()
438  return ret
439 
440  def init(self, drop=False):
441  '''Initializes a database.
442  '''
443  logging.info('Initializing database...')
444  if drop:
445  logging.debug('Dropping tables...')
446  self.metadata.drop_all(self.engine)
447  self._is_valid = False
448  else:
449  if not self._is_valid:
450  logging.debug('Creating tables...')
451  self.get_dbtype(Tag).__table__.create(bind = self.engine)
452  self.get_dbtype(Payload).__table__.create(bind = self.engine)
453  self.get_dbtype(IOV).__table__.create(bind = self.engine)
454  self.get_dbtype(TagLog).__table__.create(bind = self.engine)
455  self.get_dbtype(GlobalTag).__table__.create(bind = self.engine)
456  self.get_dbtype(GlobalTagMap).__table__.create(bind = self.engine)
457  self._is_valid = True
458 
459 def getSessionOnMasterDB( session1, session2 ):
460  key = '%s/%s'
461  sessiondict = { }
462  sessiondict[key %(session1._url.drivername,session1._url.host)] = session1
463  sessiondict[key %(session2._url.drivername,session2._url.host)] = session2
464  masterkey = key %('oracle',ONLINEORAPRO)
465  if masterkey in sessiondict.keys():
466  return sessiondict[masterkey]
467  adgkey = key %('oracle',ORAPRO)
468  if adgkey in sessiondict.keys():
469  return sessiondict[adgkey]
470  frontierkey = key %('frontier',PRO)
471  if frontierkey in sessiondict.keys():
472  return sessiondict[frontierkey]
473  # default case: frontier on pro
474  conn = Connection(make_url())
475  session = conn.session()
476  # is it required?
477  session._conn = conn
478  return session
479 
480 # Connection helpers
482  import subprocess
483  return subprocess.Popen(['cmsGetFnConnect', 'frontier://%s' % database], stdout = subprocess.PIPE).communicate()[0].strip()
484 
485 def _getCMSSQLAlchemyConnectionString(technology,service,schema_name):
486  if technology == 'frontier':
487  import urllib
488  return '%s://@%s/%s' % ('oracle+frontier', urllib.quote_plus(_getCMSFrontierConnectionString(service)), schema_name )
489  elif technology == 'oracle':
490  return '%s://%s@%s' % (technology, schema_name, service)
491 
492 # Entry point
493 def make_url(database='pro',read_only = True):
494  if database.startswith('sqlite:') or database.startswith('sqlite_file:'):
495  ignore, database = database.split(':',1)
496 
497  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
498  database, schema = database.split(':')
499 
500  officialdbs = {
501  # frontier
502  'pro' : ('frontier','PromptProd', { 'R': schema_name }, ),
503  'arc' : ('frontier','FrontierArc', { 'R': schema_name }, ),
504  'int' : ('frontier','FrontierInt', { 'R': schema_name }, ),
505  'dev' : ('frontier','FrontierPrep', { 'R': schema_name }, ),
506  # oracle adg
507  'orapro': ('oracle', 'cms_orcon_adg', { 'R': dbreader_user_name }, ),
508  'oraarc': ('oracle', 'cmsarc_lb', { 'R': dbreader_user_name }, ),
509  # oracle masters
510  'oraint': ('oracle', 'cms_orcoff_int', { 'R': dbreader_user_name,
511  'W': dbwriter_user_name }, ),
512  'oradev': ('oracle', 'cms_orcoff_prep', { 'R': dbreader_user_name,
513  'W': devdbwriter_user_name }, ),
514  'onlineorapro': ('oracle', 'cms_orcon_prod', { 'R': dbreader_user_name,
515  'W': dbwriter_user_name }, ),
516  'onlineoraint': ('oracle', 'cmsintr_lb', { 'R': dbreader_user_name,
517  'W': dbwriter_user_name }, ),
518  }
519 
520  if database in officialdbs.keys():
521  key = ('R' if read_only else 'W')
522  mapping = officialdbs[database]
523  tech = mapping[0]
524  service = mapping[1]
525  schema_dict = mapping[2]
526  if key in schema_dict.keys():
527  database = _getCMSSQLAlchemyConnectionString(tech,service,schema_dict[key])
528  else:
529  raise Exception("Read-only database %s://%s cannot be accessed in update mode." %(tech,service))
530 
531  logging.debug('connection string set to "%s"' % database)
532 
533  try:
534  url = sqlalchemy.engine.url.make_url(database)
535  except sqlalchemy.exc.ArgumentError:
536  url = sqlalchemy.engine.url.make_url('sqlite:///%s' % database)
537  return url
538 
539 def connect(url, authPath=None, verbose=0):
540  '''Returns a Connection instance to the CMS Condition DB.
541 
542  See database_help for the description of the database parameter.
543 
544  The verbosity level is as follows:
545 
546  0 = No output (default).
547  1 = SQL statements issued, including their parameters.
548  2 = In addition, results of the queries (all rows and the column headers).
549  '''
550 
551  if url.drivername == 'oracle':
552  if url.username is None:
553  logging.error('Could not resolve the username for the connection %s. Please provide a connection in the format oracle://[user]:[pass]@[host]' %url )
554  raise Exception('Connection format error: %s' %url )
555  if url.password is None:
556  if authPath is None:
557  if authPathEnvVar in os.environ:
558  authPath = os.environ[authPathEnvVar]
559  authFile = None
560  if authPath is not None:
561  authFile = os.path.join(authPath,'.netrc')
562  if authFile is not None:
563  entryKey = url.host.lower()+"/"+url.username.lower()
564  logging.debug('Looking up credentials for %s in file %s ' %(entryKey,authFile) )
565  import netrc
566  params = netrc.netrc( authFile ).authenticators(entryKey)
567  if params is not None:
568  (username, account, password) = params
569  url.password = password
570  else:
571  msg = 'The entry %s has not been found in the .netrc file.' %entryKey
572  raise TypeError(msg)
573  else:
574  import getpass
575  pwd = getpass.getpass('Password for %s: ' % str(url))
576  if pwd is None or pwd == '':
577  pwd = getpass.getpass('Password for %s: ' % str(url))
578  if pwd is None or pwd == '':
579  raise Exception('Empty password provided, bailing out...')
580  url.password = pwd
581 
582  if verbose >= 1:
583  logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
584 
585  if verbose >= 2:
586  logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG)
587 
588  return Connection(url)
589 
590 
591 def _exists(session, primary_key, value):
592  ret = None
593  try:
594  ret = session.query(primary_key).\
595  filter(primary_key == value).\
596  count() != 0
597  except sqlalchemy.exc.OperationalError:
598  pass
599 
600  return ret
601 
602 def _inserted_before(timestamp):
603  '''To be used inside filter().
604  '''
605 
606  if timestamp is None:
607  # XXX: Returning None does not get optimized (skipped) by SQLAlchemy,
608  # and returning True does not work in Oracle (generates "and 1"
609  # which breaks Oracle but not SQLite). For the moment just use
610  # this dummy condition.
611  return sqlalchemy.literal(True) == sqlalchemy.literal(True)
612 
613  return conddb.IOV.insertion_time <= _parse_timestamp(timestamp)
614 
615 def listObject(session, name, snapshot=None):
616 
617  is_tag = _exists(session, Tag.name, name)
618  result = {}
619  if is_tag:
620  result['type'] = 'Tag'
621  result['name'] = session.query(Tag).get(name).name
622  result['timeType'] = session.query(Tag.time_type).\
623  filter(Tag.name == name).\
624  scalar()
625 
626  result['iovs'] = session.query(IOV.since, IOV.insertion_time, IOV.payload_hash, Payload.object_type).\
627  join(IOV.payload).\
628  filter(
629  IOV.tag_name == name,
630  _inserted_before(snapshot),
631  ).\
632  order_by(IOV.since.desc(), IOV.insertion_time.desc()).\
633  from_self().\
634  order_by(IOV.since, IOV.insertion_time).\
635  all()
636 
637  try:
638  is_global_tag = _exists(session, GlobalTag.name, name)
639  if is_global_tag:
640  result['type'] = 'GlobalTag'
641  result['name'] = session.query(GlobalTag).get(name)
642  result['tags'] = session.query(GlobalTagMap.record, GlobalTagMap.label, GlobalTagMap.tag_name).\
643  filter(GlobalTagMap.global_tag_name == name).\
644  order_by(GlobalTagMap.record, GlobalTagMap.label).\
645  all()
646  except sqlalchemy.exc.OperationalError:
647  sys.stderr.write("No table for GlobalTags found in DB.\n\n")
648 
649  if not is_tag and not is_global_tag:
650  raise Exception('There is no tag or global tag named %s in the database.' % name)
651 
652  return result
653 
654 def getPayload(session, hash):
655  # get payload from DB:
656  data, payloadType = session.query(Payload.data, Payload.object_type).filter(Payload.hash == hash).one()
657  return data
def __getitem__(cls, key)
Definition: conddblib.py:57
def init(self, drop=False)
Definition: conddblib.py:440
def listObject(session, name, snapshot=None)
Definition: conddblib.py:615
def getPayload(session, hash)
Definition: conddblib.py:654
def is_valid(self)
Definition: conddblib.py:428
def metadata(self)
Definition: conddblib.py:405
def getSessionOnMasterDB(session1, session2)
Definition: conddblib.py:459
def is_oracle(self)
Definition: conddblib.py:413
def __init__(self, url)
Definition: conddblib.py:334
def _getCMSFrontierConnectionString(database)
Definition: conddblib.py:481
def is_sqlite(self)
Definition: conddblib.py:417
static void * communicate(void *obj)
Definition: DQMNet.cc:1251
def make_url(database='pro', read_only=True)
Definition: conddblib.py:493
def is_read_only(self)
Definition: conddblib.py:421
def make_dbtype(backendName, schemaName, baseType)
Definition: conddblib.py:215
def is_frontier(self)
Definition: conddblib.py:409
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:539
def __call__(cls, value)
Definition: conddblib.py:67
def _getCMSSQLAlchemyConnectionString(technology, service, schema_name)
Definition: conddblib.py:485
def get_dbtype(self, theType)
Definition: conddblib.py:389
dbl *** dir
Definition: mlp_gen.cc:35
def is_official(self)
Definition: conddblib.py:425
#define str(s)
def _inserted_before(timestamp)
Definition: conddblib.py:602
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:591
double scalar(const CLHEP::HepGenMatrix &m)
Return the matrix as a scalar. Raise an assertion if the matris is not .
Definition: matutil.cc:183