Source code for pacifica.uniqueid.orm

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""ORM for index server."""
import logging
from time import sleep
from peewee import OperationalError, CharField, IntegerField, BigIntegerField, Model
from playhouse.db_url import connect
from pacifica.uniqueid.config import get_config

SCHEMA_MAJOR = 1
SCHEMA_MINOR = 0
DB = connect(get_config().get('database', 'peewee_url'))


[docs]class OrmSync(object): """ Special module for syncing the orm. This module should incorporate a schema migration strategy. The supported versions migrating forward must be in a versions array containing tuples for major and minor versions. The version tuples are directly translated to method names in the ``OrmSync`` class for the update between those versions. Example Version Control:: class OrmSync: versions = [ (0, 1), (0, 2), (1, 0), (1, 1) ] def update_0_1_to_0_2(): pass def update_0_2_to_1_0(): pass The body of an update method should follow peewee migration practices. http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#migrate """ versions = [ (0, 0), (1, 0) ]
[docs] @staticmethod def dbconn_blocking(): """Wait for the db connection.""" dbcon_attempts = get_config().getint('database', 'connect_attempts') dbcon_wait = get_config().getint('database', 'connect_wait') while dbcon_attempts: try: UniqueIndex.database_connect() return except OperationalError: # couldnt connect, potentially wait and try again sleep(dbcon_wait) dbcon_attempts -= 1 raise OperationalError('Failed database connect retry.')
[docs] @classmethod def update_0_0_to_1_0(cls): """Update by adding the boolean column.""" if not UniqueIndex.table_exists(): UniqueIndex.create_table()
[docs] @classmethod def update_tables(cls): """Update the database to the current version.""" verlist = cls.versions db_ver = UniqueIndexSystem.get_version() if verlist.index(verlist[-1]) == verlist.index(db_ver): # we have the current version don't update return with UniqueIndex.atomic(): for db_ver in verlist[verlist.index(db_ver):-1]: next_db_ver = verlist[verlist.index(db_ver)+1] method_name = 'update_{}_to_{}'.format( '{}_{}'.format(*db_ver), '{}_{}'.format(*next_db_ver) ) getattr(cls, method_name)() UniqueIndexSystem.drop_table() UniqueIndexSystem.create_table() UniqueIndexSystem.get_or_create_version()
[docs]class UniqueIndexBase(Model): """UniqueIndex base model for database setup.""" # pylint: disable=too-few-public-methods class Meta(object): """Map to the database connected above.""" database = DB only_save_dirty = True
# pylint: enable=too-few-public-methods
[docs]class UniqueIndexSystem(UniqueIndexBase): """UniqueIndex Schema Version Model.""" part = CharField(primary_key=True) value = IntegerField(default=-1)
[docs] @classmethod def get_or_create_version(cls): """Set or create the current version of the schema.""" if not cls.table_exists(): return (0, 0) major = cls.get_or_create(part='major', value=SCHEMA_MAJOR) minor = cls.get_or_create(part='minor', value=SCHEMA_MINOR) return (major, minor)
[docs] @classmethod def get_version(cls): """Get the current version as a tuple.""" if not cls.table_exists(): return (0, 0) return (cls.get(part='major').value, cls.get(part='minor').value)
[docs] @classmethod def is_equal(cls): """Check to see if schema version matches code version.""" major, minor = cls.get_version() return major == SCHEMA_MAJOR and minor == SCHEMA_MINOR
[docs] @classmethod def is_safe(cls): """Check to see if the schema version is safe for the code.""" major, _minor = cls.get_version() return major == SCHEMA_MAJOR
[docs]class UniqueIndex(UniqueIndexBase): """Auto-generated by pwiz maps a python record to a mysql table.""" idid = CharField(primary_key=True, db_column='id') index = BigIntegerField(db_column='index')
[docs] @classmethod def atomic(cls): """Get the atomic context or decorator.""" # pylint: disable=no-member return cls._meta.database.atomic()
# pylint: enable=no-member
[docs] @classmethod def database_connect(cls): """ Make sure database is connected. Trying to connect a second time doesnt cause any problems. """ peewee_logger = logging.getLogger('peewee') peewee_logger.debug('Connecting to database.') # pylint: disable=no-member if not cls._meta.database.is_closed(): # pragma no cover cls._meta.database.close() cls._meta.database.connect()
# pylint: enable=no-member
[docs] @classmethod def database_close(cls): """ Close the database connection. Closing already closed database throws an error so catch it and continue on. """ peewee_logger = logging.getLogger('peewee') peewee_logger.debug('Closing database connection.') # pylint: disable=no-member if not cls._meta.database.is_closed(): # pragma no cover cls._meta.database.close()
# pylint: enable=no-member
[docs]def update_index(id_range, id_mode): """Update the index for a mode and returns a unique start and stop index.""" index = -1 id_range = id_range with UniqueIndex.atomic(): if id_range and id_mode and id_range > 0: record = UniqueIndex.get_or_create( idid=id_mode, defaults={'index': 1})[0] index = int(record.index) record.index = index + id_range record.save() else: index = -1 id_range = int(-1) return (index, id_range)