initial draft

This commit is contained in:
Konsta Vesterinen
2013-02-18 18:57:14 +02:00
parent 94b1657697
commit d58ea13482
10 changed files with 195 additions and 4 deletions

9
.travis.yml Normal file
View File

@@ -0,0 +1,9 @@
language: python
python:
- 2.5
- 2.6
- 2.7
install:
- pip install -q -e . --use-mirrors
script:
- python setup.py test

10
CHANGES.rst Normal file
View File

@@ -0,0 +1,10 @@
Changelog
---------
Various utility functions that I use alongside SQLAlchemy.
0.1.0 (12.1.2013)
^^^^^^^^^^^^^^^^
- Initial public release

27
LICENSE Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2012, Konsta Vesterinen
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The names of the contributors may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

7
MANIFEST.in Normal file
View File

@@ -0,0 +1,7 @@
include CHANGES.rst LICENSE README.rst
recursive-include tests *
recursive-exclude tests *.pyc
recursive-include docs *
recursive-exclude docs *.pyc
prune docs/_build
exclude docs/_themes/.git

View File

@@ -1,4 +0,0 @@
sqlalchemy-utils
================
Various utility functions that I use alongside SQLAlchemy.

12
README.rst Normal file
View File

@@ -0,0 +1,12 @@
SQLAlchemy-Utils
================
Various utility functions that I use alongside SQLAlchemy.
Resources
---------
- `Documentation <http://sqlalchemy-utils.readthedocs.org/>`_
- `Issue Tracker <http://github.com/kvesteri/sqlalchemy-utils/issues>`_
- `Code <http://github.com/kvesteri/sqlalchemy-utils/>`_

5
requirements-dev.txt Normal file
View File

@@ -0,0 +1,5 @@
-r requirements.txt
pytest==2.2.3
Pygments==1.2
Jinja2==2.3
docutils>=0.10

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
SQLAlchemy==0.7.8

53
setup.py Normal file
View File

@@ -0,0 +1,53 @@
"""
SQLAlchemy-Searchable
---------------------
Various utility functions I use with SQLAlchemy.
"""
from setuptools import setup, Command
import subprocess
class PyTest(Command):
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
errno = subprocess.call(['py.test'])
raise SystemExit(errno)
setup(
name='SQLAlchemy-Utils',
version='0.1',
url='https://github.com/kvesteri/sqlalchemy-utils',
license='BSD',
author='Konsta Vesterinen',
author_email='konsta@fastmonkeys.com',
description=(
'Various utility functions I use with SQLAlchemy.'
),
long_description=__doc__,
packages=['sqlalchemy_utils'],
zip_safe=False,
include_package_data=True,
platforms='any',
install_requires=[
'SQLAlchemy==0.7.8',
],
cmdclass={'test': PyTest},
classifiers=[
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development :: Libraries :: Python Modules'
]
)

View File

@@ -0,0 +1,71 @@
from flask import request
from sqlalchemy.orm.mapper import Mapper
from sqlalchemy.orm.query import _ColumnEntity
from sqlalchemy.sql.expression import desc, asc
def sort_query(query, sort):
"""
Applies an sql ORDER BY for given query
:param query: query to be modified
:param sort: string that defines the label or column to sort the query by
"""
entities = [entity.entity_zero.class_ for entity in query._entities]
for mapper in query._join_entities:
if isinstance(mapper, Mapper):
entities.append(mapper.class_)
else:
entities.append(mapper)
# get all label names for queries such as:
# db.session.query(Category, db.func.count(Article.id).label('articles'))
labels = []
for entity in query._entities:
if isinstance(entity, _ColumnEntity) and entity._label_name:
labels.append(entity._label_name)
sort = request.args.get('sort', sort)
if not sort:
return query
if sort[0] == '-':
func = desc
sort = sort[1:]
else:
func = asc
component = None
parts = sort.split('-')
if len(parts) > 1:
component = parts[0]
sort = parts[1]
if sort in labels:
query = query.order_by(func(sort))
else:
for entity in entities:
if component and entity.__table__.name != component:
continue
if sort in entity.__table__.columns:
try:
attr = getattr(entity, sort)
query = query.order_by(func(attr))
except AttributeError:
pass
break
return query
def escape_like(string, escape_char='*'):
"""
Escapes the string paremeter used in SQL LIKE expressions
:param string: a string to escape
:param escape_char: escape character
"""
return (
string
.replace(escape_char, escape_char * 2)
.replace('%', escape_char + '%')
.replace('_', escape_char + '_')
)