Added SmartList, 0.3 release
This commit is contained in:
@@ -4,6 +4,13 @@ Changelog
|
|||||||
Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
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)
|
0.2.0 (2013-03-01)
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@@ -6,12 +6,16 @@
|
|||||||
SQLAlchemy-Utils
|
SQLAlchemy-Utils
|
||||||
================
|
================
|
||||||
|
|
||||||
|
SQLAlchemy-Utils provides various utility classes and functions for SQLAlchemy.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
API Documentation
|
API Documentation
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
.. module:: sqlalchemy_utils
|
.. module:: sqlalchemy_utils
|
||||||
|
.. autoclass:: SmartList
|
||||||
|
:members:
|
||||||
.. autofunction:: sort_query
|
.. autofunction:: sort_query
|
||||||
.. autofunction:: escape_like
|
.. autofunction:: escape_like
|
||||||
|
|
||||||
|
2
setup.py
2
setup.py
@@ -24,7 +24,7 @@ class PyTest(Command):
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='SQLAlchemy-Utils',
|
name='SQLAlchemy-Utils',
|
||||||
version='0.2',
|
version='0.3',
|
||||||
url='https://github.com/kvesteri/sqlalchemy-utils',
|
url='https://github.com/kvesteri/sqlalchemy-utils',
|
||||||
license='BSD',
|
license='BSD',
|
||||||
author='Konsta Vesterinen',
|
author='Konsta Vesterinen',
|
||||||
|
@@ -1,10 +1,41 @@
|
|||||||
from sqlalchemy.orm import defer
|
from sqlalchemy.orm import defer
|
||||||
|
from sqlalchemy.orm.collections import InstrumentedList
|
||||||
from sqlalchemy.orm.mapper import Mapper
|
from sqlalchemy.orm.mapper import Mapper
|
||||||
from sqlalchemy.orm.query import _ColumnEntity
|
from sqlalchemy.orm.query import _ColumnEntity
|
||||||
from sqlalchemy.orm.properties import ColumnProperty
|
from sqlalchemy.orm.properties import ColumnProperty
|
||||||
from sqlalchemy.sql.expression import desc, asc
|
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):
|
def sort_query(query, sort):
|
||||||
"""
|
"""
|
||||||
Applies an sql ORDER BY for given query. This function can be easily used
|
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 import create_engine
|
||||||
>>> from sqlalchemy.orm import sessionmaker
|
>>> from sqlalchemy.orm import sessionmaker
|
||||||
>>> from sqlalchemy.ext.declarative import declarative_base
|
>>> from sqlalchemy.ext.declarative import declarative_base
|
||||||
>>> from sqlalchemy_utils import escape_like, sort_query
|
>>> from sqlalchemy_utils import sort_query
|
||||||
>>>
|
>>>
|
||||||
>>>
|
>>>
|
||||||
>>> engine = create_engine(
|
>>> engine = create_engine(
|
||||||
|
28
tests.py
28
tests.py
@@ -1,10 +1,11 @@
|
|||||||
|
from pytest import raises
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
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(
|
engine = create_engine(
|
||||||
@@ -29,8 +30,31 @@ class Article(Base):
|
|||||||
category_id = sa.Column(sa.Integer, sa.ForeignKey(Category.id))
|
category_id = sa.Column(sa.Integer, sa.ForeignKey(Category.id))
|
||||||
|
|
||||||
category = sa.orm.relationship(
|
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):
|
class TestEscapeLike(object):
|
||||||
|
Reference in New Issue
Block a user