0.4 release
This commit is contained in:
@@ -5,6 +5,13 @@ Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
||||
|
||||
|
||||
|
||||
0.4.0 (2013-03-01)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- Renamed SmartList to InstrumentedList
|
||||
- Added instrumented_list decorator
|
||||
|
||||
|
||||
0.3.0 (2013-03-01)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
2
setup.py
2
setup.py
@@ -24,7 +24,7 @@ class PyTest(Command):
|
||||
|
||||
setup(
|
||||
name='SQLAlchemy-Utils',
|
||||
version='0.3',
|
||||
version='0.4',
|
||||
url='https://github.com/kvesteri/sqlalchemy-utils',
|
||||
license='BSD',
|
||||
author='Konsta Vesterinen',
|
||||
|
@@ -1,39 +1,28 @@
|
||||
from functools import wraps
|
||||
from sqlalchemy.orm import defer
|
||||
from sqlalchemy.orm.collections import InstrumentedList
|
||||
from sqlalchemy.orm.collections import InstrumentedList as _InstrumentedList
|
||||
from sqlalchemy.orm.mapper import Mapper
|
||||
from sqlalchemy.orm.query import _ColumnEntity
|
||||
from sqlalchemy.orm.properties import ColumnProperty
|
||||
from sqlalchemy.sql.expression import desc, asc
|
||||
|
||||
|
||||
class SmartList(InstrumentedList):
|
||||
def has(self, attr):
|
||||
"""
|
||||
Returns True if any member of this collection has given attribute
|
||||
defined.
|
||||
class InstrumentedList(_InstrumentedList):
|
||||
"""Enhanced version of SQLAlchemy InstrumentedList. Provides some
|
||||
additional functionality."""
|
||||
|
||||
Example syntax:
|
||||
def any(self, attr):
|
||||
return any(getattr(item, attr) for item in self)
|
||||
|
||||
>>> Category.articles.has('name')
|
||||
def all(self, attr):
|
||||
return all(getattr(item, attr) for item in self)
|
||||
|
||||
:param attr: collection member attribute name
|
||||
"""
|
||||
adapter = self._sa_adapter
|
||||
owner_class = adapter.owner_state.class_
|
||||
relation = getattr(owner_class, adapter._key).property
|
||||
relation_class = relation.mapper.class_
|
||||
|
||||
if not hasattr(relation_class, attr):
|
||||
raise AttributeError(
|
||||
'Class %s does not have attribute named %s' %
|
||||
(relation_class.__name__, attr)
|
||||
)
|
||||
|
||||
for record in self:
|
||||
if getattr(record, attr):
|
||||
return True
|
||||
|
||||
return False
|
||||
def instrumented_list(f):
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
return InstrumentedList([item for item in f(*args, **kwargs)])
|
||||
return wrapper
|
||||
|
||||
|
||||
def sort_query(query, sort):
|
||||
|
20
tests.py
20
tests.py
@@ -1,11 +1,10 @@
|
||||
from pytest import raises
|
||||
import sqlalchemy as sa
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
from sqlalchemy_utils import escape_like, sort_query, SmartList
|
||||
from sqlalchemy_utils import escape_like, sort_query, InstrumentedList
|
||||
|
||||
|
||||
engine = create_engine(
|
||||
@@ -34,27 +33,22 @@ class Article(Base):
|
||||
primaryjoin=category_id == Category.id,
|
||||
backref=sa.orm.backref(
|
||||
'articles',
|
||||
collection_class=SmartList
|
||||
collection_class=InstrumentedList
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class TestSmartList(object):
|
||||
def test_has_raises_error_for_unknown_attribute(self):
|
||||
category = Category()
|
||||
with raises(AttributeError):
|
||||
category.articles.has('unknown_column')
|
||||
|
||||
def test_has_returns_true_if_member_has_attr_defined(self):
|
||||
class TestInstrumentedList(object):
|
||||
def test_any_returns_true_if_member_has_attr_defined(self):
|
||||
category = Category()
|
||||
category.articles.append(Article())
|
||||
category.articles.append(Article(name=u'some name'))
|
||||
assert category.articles.has('name')
|
||||
assert category.articles.any('name')
|
||||
|
||||
def test_has_returns_false_if_no_member_has_attr_defined(self):
|
||||
def test_any_returns_false_if_no_member_has_attr_defined(self):
|
||||
category = Category()
|
||||
category.articles.append(Article())
|
||||
assert not category.articles.has('name')
|
||||
assert not category.articles.any('name')
|
||||
|
||||
|
||||
class TestEscapeLike(object):
|
||||
|
Reference in New Issue
Block a user