From c9c49794528529cca1b119610261d5424edfac77 Mon Sep 17 00:00:00 2001 From: Konsta Vesterinen Date: Mon, 29 Apr 2013 18:18:21 +0300 Subject: [PATCH] Added ColorType --- CHANGES.rst | 6 ++++ docs/index.rst | 58 +++++++++++++++++++++++++++++------- requirements.txt | 1 + setup.py | 5 ++-- sqlalchemy_utils/__init__.py | 2 ++ sqlalchemy_utils/types.py | 24 +++++++++++++++ tests/test_color.py | 28 +++++++++++++++++ tests/test_email.py | 2 +- 8 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 tests/test_color.py diff --git a/CHANGES.rst b/CHANGES.rst index 8ea3dd6..a792440 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.10.0 (2013-04-29) +^^^^^^^^^^^^^^^^^^^ + +- Added ColorType + + 0.9.1 (2013-04-15) ^^^^^^^^^^^^^^^^^^ diff --git a/docs/index.rst b/docs/index.rst index de317bf..85f67f4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,23 +8,23 @@ SQLAlchemy-Utils SQLAlchemy-Utils provides various utility classes and functions for SQLAlchemy. -ScalarList ----------- +ScalarListType +-------------- -ScalarList type provides convenient way for saving multiple scalar values in one -column. ScalarList works like list on python side and saves the result as comma-separated list +ScalarListType type provides convenient way for saving multiple scalar values in one +column. ScalarListType works like list on python side and saves the result as comma-separated list in the database (custom separators can also be used). Example :: - from sqlalchemy_utils import ScalarList + from sqlalchemy_utils import ScalarListType class User(Base): __tablename__ = 'user' id = db.Column(db.Integer, autoincrement=True) - hobbies = db.Column(ScalarList()) + hobbies = db.Column(ScalarListType()) user = User() @@ -37,13 +37,13 @@ You can easily set up integer lists too: :: - from sqlalchemy_utils import ScalarList + from sqlalchemy_utils import ScalarListType class Player(Base): __tablename__ = 'player' id = db.Column(db.Integer, autoincrement=True) - points = db.Column(ScalarList(int)) + points = db.Column(ScalarListType(int)) player = Player() @@ -51,8 +51,46 @@ You can easily set up integer lists too: session.commit() -NumberRange ------------ +ColorType +--------- + +ColorType provides a way for saving Color (from colour package) objects into database. +ColorType saves Color objects as strings on the way in and converts them back to objects when querying the database. + +:: + + + from colour import Color + from sqlalchemy_utils import ColorType + + + class Document(Base): + __tablename__ = 'player' + id = db.Column(db.Integer, autoincrement=True) + name = db.Column(db.Unicode(50)) + background_color = db.Column(ColorType) + + + document = Document() + document.background_color = Color('#F5F5F5') + session.commit() + + +Querying the database returns Color objects: + +:: + + document = session.query(Document).first() + + document.background_color.hex + # '#f5f5f5' + + +For more information about colour package and Color object, see https://github.com/vaab/colour + + +NumberRangeType +--------------- NumberRangeType provides way for saving range of numbers into database. diff --git a/requirements.txt b/requirements.txt index 29149dc..7e90aa4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ SQLAlchemy>=0.7.8 psycopg2>=2.4.6 phonenumbers>=5.4b1 +colour==0.0.2 diff --git a/setup.py b/setup.py index efd90b3..fcb6e2f 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ class PyTest(Command): setup( name='SQLAlchemy-Utils', - version='0.9.1', + version='0.10.0', url='https://github.com/kvesteri/sqlalchemy-utils', license='BSD', author='Konsta Vesterinen', @@ -40,7 +40,8 @@ setup( install_requires=[ 'SQLAlchemy>=0.7.8', 'psycopg2>=2.4.6', - 'phonenumbers>=5.4b1' + 'phonenumbers>=5.4b1', + 'colour==0.0.2' ], cmdclass={'test': PyTest}, classifiers=[ diff --git a/sqlalchemy_utils/__init__.py b/sqlalchemy_utils/__init__.py index 52b1d80..59cdcab 100644 --- a/sqlalchemy_utils/__init__.py +++ b/sqlalchemy_utils/__init__.py @@ -1,6 +1,7 @@ from .functions import sort_query, defer_except, escape_like from .merge import merge, Merger from .types import ( + ColorType, EmailType, instrumented_list, InstrumentedList, @@ -21,6 +22,7 @@ __all__ = ( escape_like, instrumented_list, merge, + ColorType, EmailType, InstrumentedList, Merger, diff --git a/sqlalchemy_utils/types.py b/sqlalchemy_utils/types.py index e7180ca..c215df9 100644 --- a/sqlalchemy_utils/types.py +++ b/sqlalchemy_utils/types.py @@ -1,4 +1,5 @@ import phonenumbers +from colour import Color from functools import wraps import sqlalchemy as sa from sqlalchemy.orm.collections import InstrumentedList as _InstrumentedList @@ -84,6 +85,29 @@ class PhoneNumberType(types.TypeDecorator): return value +class ColorType(types.TypeDecorator): + """ + Changes Color objects to a string representation on the way in and + changes them back to Color objects on the way out. + """ + STORE_FORMAT = 'hex' + impl = types.Unicode(20) + + def __init__(self, max_length=20, *args, **kwargs): + super(ColorType, self).__init__(*args, **kwargs) + self.impl = types.Unicode(max_length) + + def process_bind_param(self, value, dialect): + if value: + return getattr(value, self.STORE_FORMAT) + return value + + def process_result_value(self, value, dialect): + if value: + return Color(value) + return value + + class ScalarListException(Exception): pass diff --git a/tests/test_color.py b/tests/test_color.py new file mode 100644 index 0000000..e7d71b4 --- /dev/null +++ b/tests/test_color.py @@ -0,0 +1,28 @@ +from colour import Color +import sqlalchemy as sa +from sqlalchemy_utils import ColorType +from tests import DatabaseTestCase + + +class TestColorType(DatabaseTestCase): + def create_models(self): + class Document(self.Base): + __tablename__ = 'document' + id = sa.Column(sa.Integer, primary_key=True) + bg_color = sa.Column(ColorType) + + def __repr__(self): + return 'Document(%r)' % self.id + + self.Document = Document + + def test_color_parameter_processing(self): + document = self.Document( + bg_color=Color(u'white') + ) + + self.session.add(document) + self.session.commit() + + document = self.session.query(self.Document).first() + assert document.bg_color.hex == Color(u'white').hex diff --git a/tests/test_email.py b/tests/test_email.py index 16c98cf..c4d0021 100644 --- a/tests/test_email.py +++ b/tests/test_email.py @@ -11,7 +11,7 @@ class TestEmailType(DatabaseTestCase): email = sa.Column(EmailType) def __repr__(self): - return 'Building(%r)' % self.id + return 'User(%r)' % self.id self.User = User