From 6beffc8d96f5753c45cf5168895ed954a853d147 Mon Sep 17 00:00:00 2001 From: Konsta Vesterinen Date: Tue, 23 Jul 2013 11:27:26 +0300 Subject: [PATCH] Added utility functions identity, is_auto_assigned_date_column and declarative_base --- CHANGES.rst | 6 ++++ docs/index.rst | 4 +++ setup.py | 2 +- sqlalchemy_utils/__init__.py | 2 +- sqlalchemy_utils/functions.py | 57 +++++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index b1f4e66..f300620 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,12 @@ Changelog Here you can see the full list of changes between each SQLAlchemy-Utils release. +0.15.1 (2013-07-22) +^^^^^^^^^^^^^^^^^^^ + +- Added utility functions declarative_base, identity and is_auto_assigned_date_column + + 0.15.0 (2013-07-22) ^^^^^^^^^^^^^^^^^^^ diff --git a/docs/index.rst b/docs/index.rst index 495ee72..fd69e30 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -206,6 +206,10 @@ API Documentation .. autofunction:: escape_like .. autofunction:: non_indexed_foreign_keys .. autofunction:: is_indexed_foreign_key +.. autofunction:: identity +.. autofunction:: is_auto_assigned_date_column +.. autofunction:: declarative_base + .. include:: ../CHANGES.rst diff --git a/setup.py b/setup.py index f18be5f..dfa4da2 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ class PyTest(Command): setup( name='SQLAlchemy-Utils', - version='0.15.0', + version='0.15.1', url='https://github.com/kvesteri/sqlalchemy-utils', license='BSD', author='Konsta Vesterinen', diff --git a/sqlalchemy_utils/__init__.py b/sqlalchemy_utils/__init__.py index 1bc660b..80a6f89 100644 --- a/sqlalchemy_utils/__init__.py +++ b/sqlalchemy_utils/__init__.py @@ -26,7 +26,7 @@ from .types import ( ) -__version__ = '0.15.0' +__version__ = '0.15.1' __all__ = ( diff --git a/sqlalchemy_utils/functions.py b/sqlalchemy_utils/functions.py index a2e8eed..1446f8b 100644 --- a/sqlalchemy_utils/functions.py +++ b/sqlalchemy_utils/functions.py @@ -1,4 +1,5 @@ from collections import defaultdict +import sqlalchemy as sa from sqlalchemy.orm import defer from sqlalchemy.orm.mapper import Mapper from sqlalchemy.orm.query import _ColumnEntity @@ -295,3 +296,59 @@ def is_indexed_foreign_key(constraint): if index_column_names == set(constraint.columns): return True return False + + +def declarative_base(model): + """ + Returns the declarative base for given model class. + + :param model: SQLAlchemy declarative model + """ + for parent in model.__bases__: + try: + parent.metadata + return declarative_base(parent) + except AttributeError: + pass + return model + + +def is_auto_assigned_date_column(column): + """ + Returns whether or not given SQLAlchemy Column object's is auto assigned + DateTime or Date. + + :param column: SQLAlchemy Column object + """ + return ( + ( + isinstance(column.type, sa.DateTime) or + isinstance(column.type, sa.Date) + ) + and + ( + column.default or + column.server_default or + column.onupdate or + column.server_onupdate + ) + ) + + +def identity(obj): + """ + Return the identity of given sqlalchemy declarative model instance as a + tuple. This differs from obj._sa_instance_state.identity in a way that it + always returns the identity even if object is still in transient state ( + new object that is not yet persisted into database). + + :param obj: SQLAlchemy declarative model object + """ + id_ = [] + for attr in obj._sa_class_manager.values(): + prop = attr.property + if isinstance(prop, sa.orm.ColumnProperty): + column = prop.columns[0] + if column.primary_key: + id_.append(getattr(obj, column.name)) + return tuple(id_)