Added SmartList, 0.3 release

This commit is contained in:
Konsta Vesterinen
2013-03-07 11:09:49 +02:00
parent 135e75d2dd
commit a1955c3a00
5 changed files with 70 additions and 4 deletions

View File

@@ -4,6 +4,13 @@ Changelog
Here you can see the full list of changes between each SQLAlchemy-Utils release.
0.3.0 (2013-03-01)
^^^^^^^^^^^^^^^^^^
- Added new collection class SmartList
0.2.0 (2013-03-01)
^^^^^^^^^^^^^^^^^^

View File

@@ -6,12 +6,16 @@
SQLAlchemy-Utils
================
SQLAlchemy-Utils provides various utility classes and functions for SQLAlchemy.
API Documentation
-----------------
.. module:: sqlalchemy_utils
.. autoclass:: SmartList
:members:
.. autofunction:: sort_query
.. autofunction:: escape_like

View File

@@ -24,7 +24,7 @@ class PyTest(Command):
setup(
name='SQLAlchemy-Utils',
version='0.2',
version='0.3',
url='https://github.com/kvesteri/sqlalchemy-utils',
license='BSD',
author='Konsta Vesterinen',

View File

@@ -1,10 +1,41 @@
from sqlalchemy.orm import defer
from sqlalchemy.orm.collections import 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.
Example syntax:
>>> Category.articles.has('name')
: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 sort_query(query, sort):
"""
Applies an sql ORDER BY for given query. This function can be easily used
@@ -16,7 +47,7 @@ def sort_query(query, sort):
>>> 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
>>> from sqlalchemy_utils import sort_query
>>>
>>>
>>> engine = create_engine(

View File

@@ -1,10 +1,11 @@
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
from sqlalchemy_utils import escape_like, sort_query, SmartList
engine = create_engine(
@@ -29,10 +30,33 @@ class Article(Base):
category_id = sa.Column(sa.Integer, sa.ForeignKey(Category.id))
category = sa.orm.relationship(
Category, primaryjoin=category_id == Category.id
Category,
primaryjoin=category_id == Category.id,
backref=sa.orm.backref(
'articles',
collection_class=SmartList
)
)
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):
category = Category()
category.articles.append(Article())
category.articles.append(Article(name=u'some name'))
assert category.articles.has('name')
def test_has_returns_false_if_no_member_has_attr_defined(self):
category = Category()
category.articles.append(Article())
assert not category.articles.has('name')
class TestEscapeLike(object):
def test_escapes_wildcards(self):
assert escape_like('_*%') == '*_***%'