Moved majority of the docs to doc blocks
This commit is contained in:
336
docs/index.rst
336
docs/index.rst
@@ -54,379 +54,89 @@ Data types
|
|||||||
|
|
||||||
SQLAlchemy-Utils provides various new data types for SQLAlchemy.
|
SQLAlchemy-Utils provides various new data types for SQLAlchemy.
|
||||||
|
|
||||||
|
.. module:: sqlalchemy_utils.types
|
||||||
|
|
||||||
ChoiceType
|
ChoiceType
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
ChoiceType offers way of having fixed set of choices for given column. Columns with ChoiceTypes are automatically coerced to Choice objects.
|
.. module:: sqlalchemy_utils.types.choice
|
||||||
|
|
||||||
|
.. autoclass:: ChoiceType
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
class User(self.Base):
|
|
||||||
TYPES = [
|
|
||||||
(u'admin', u'Admin'),
|
|
||||||
(u'regular-user', u'Regular user')
|
|
||||||
]
|
|
||||||
|
|
||||||
__tablename__ = 'user'
|
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
|
||||||
name = sa.Column(sa.Unicode(255))
|
|
||||||
type = sa.Column(ChoiceType(TYPES))
|
|
||||||
|
|
||||||
|
|
||||||
user = User(type=u'admin')
|
|
||||||
user.type # Choice(type='admin', value=u'Admin')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ChoiceType is very useful when the rendered values change based on user's locale:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
from babel import lazy_gettext as _
|
|
||||||
|
|
||||||
|
|
||||||
class User(self.Base):
|
|
||||||
TYPES = [
|
|
||||||
(u'admin', _(u'Admin')),
|
|
||||||
(u'regular-user', _(u'Regular user'))
|
|
||||||
]
|
|
||||||
|
|
||||||
__tablename__ = 'user'
|
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
|
||||||
name = sa.Column(sa.Unicode(255))
|
|
||||||
type = sa.Column(ChoiceType(TYPES))
|
|
||||||
|
|
||||||
|
|
||||||
user = User(type=u'admin')
|
|
||||||
user.type # Choice(type='admin', value=u'Admin')
|
|
||||||
|
|
||||||
print user.type # u'Admin'
|
|
||||||
|
|
||||||
|
|
||||||
ColorType
|
ColorType
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
ColorType provides a way for saving Color (from colour_ package) objects into database.
|
.. module:: sqlalchemy_utils.types.color
|
||||||
ColorType saves Color objects as strings on the way in and converts them back to objects when querying the database.
|
|
||||||
|
|
||||||
::
|
.. autoclass:: ColorType
|
||||||
|
|
||||||
|
|
||||||
from colour import Color
|
|
||||||
from sqlalchemy_utils import ColorType
|
|
||||||
|
|
||||||
|
|
||||||
class Document(Base):
|
|
||||||
__tablename__ = 'document'
|
|
||||||
id = sa.Column(sa.Integer, autoincrement=True)
|
|
||||||
name = sa.Column(sa.Unicode(50))
|
|
||||||
background_color = sa.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
|
|
||||||
|
|
||||||
|
|
||||||
JSONType
|
JSONType
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
JSONType offers way of saving JSON data structures to database. On PostgreSQL the underlying implementation of this data type is 'json' while on other databases its simply 'text'.
|
.. module:: sqlalchemy_utils.types.json
|
||||||
|
|
||||||
::
|
.. autoclass:: JSONType
|
||||||
|
|
||||||
|
|
||||||
from sqlalchemy_utils import JSONType
|
|
||||||
|
|
||||||
|
|
||||||
class Product(Base):
|
|
||||||
__tablename__ = 'product'
|
|
||||||
id = sa.Column(sa.Integer, autoincrement=True)
|
|
||||||
name = sa.Column(sa.Unicode(50))
|
|
||||||
details = sa.Column(JSONType)
|
|
||||||
|
|
||||||
|
|
||||||
product = Product()
|
|
||||||
product.details = {
|
|
||||||
'color': 'red',
|
|
||||||
'type': 'car',
|
|
||||||
'max-speed': '400 mph'
|
|
||||||
}
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
LocaleType
|
LocaleType
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
LocaleType saves Babel_ Locale objects into database. The Locale objects are converted to string on the way in and back to object on the way out.
|
|
||||||
|
|
||||||
In order to use LocaleType you need to install Babel_ first.
|
.. module:: sqlalchemy_utils.types.locale
|
||||||
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
from sqlalchemy_utils import LocaleType
|
|
||||||
from babel import Locale
|
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
|
||||||
__tablename__ = 'user'
|
|
||||||
id = sa.Column(sa.Integer, autoincrement=True)
|
|
||||||
name = sa.Column(sa.Unicode(50))
|
|
||||||
locale = sa.Column(LocaleType)
|
|
||||||
|
|
||||||
|
|
||||||
user = User()
|
|
||||||
user.locale = Locale('en_US')
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
Like many other types this type also supports scalar coercion:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
user.locale = 'de_DE'
|
|
||||||
user.locale # Locale('de_DE')
|
|
||||||
|
|
||||||
|
.. autoclass:: LocaleType
|
||||||
|
|
||||||
|
|
||||||
NumberRangeType
|
NumberRangeType
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
NumberRangeType provides way for saving range of numbers into database.
|
.. module:: sqlalchemy_utils.types.number_range
|
||||||
|
|
||||||
Example ::
|
|
||||||
|
|
||||||
|
|
||||||
from sqlalchemy_utils import NumberRangeType, NumberRange
|
|
||||||
|
|
||||||
|
|
||||||
class Event(Base):
|
|
||||||
__tablename__ = 'user'
|
|
||||||
id = sa.Column(sa.Integer, autoincrement=True)
|
|
||||||
name = sa.Column(sa.Unicode(255))
|
|
||||||
estimated_number_of_persons = sa.Column(NumberRangeType)
|
|
||||||
|
|
||||||
|
|
||||||
party = Event(name=u'party')
|
|
||||||
|
|
||||||
# we estimate the party to contain minium of 10 persons and at max
|
|
||||||
# 100 persons
|
|
||||||
party.estimated_number_of_persons = NumberRange(10, 100)
|
|
||||||
|
|
||||||
print party.estimated_number_of_persons
|
|
||||||
# '10-100'
|
|
||||||
|
|
||||||
|
|
||||||
NumberRange supports some arithmetic operators:
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
meeting = Event(name=u'meeting')
|
|
||||||
|
|
||||||
meeting.estimated_number_of_persons = NumberRange(20, 40)
|
|
||||||
|
|
||||||
total = (
|
|
||||||
meeting.estimated_number_of_persons +
|
|
||||||
party.estimated_number_of_persons
|
|
||||||
)
|
|
||||||
print total
|
|
||||||
# '30-140'
|
|
||||||
|
|
||||||
|
.. autoclass:: NumberRangeType
|
||||||
|
|
||||||
|
|
||||||
ScalarListType
|
ScalarListType
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
ScalarListType type provides convenient way for saving multiple scalar values in one
|
.. module:: sqlalchemy_utils.types.scalar_list
|
||||||
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 ScalarListType
|
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
|
||||||
__tablename__ = 'user'
|
|
||||||
id = sa.Column(sa.Integer, autoincrement=True)
|
|
||||||
hobbies = sa.Column(ScalarListType())
|
|
||||||
|
|
||||||
|
|
||||||
user = User()
|
|
||||||
user.hobbies = [u'football', u'ice_hockey']
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
You can easily set up integer lists too:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
from sqlalchemy_utils import ScalarListType
|
|
||||||
|
|
||||||
|
|
||||||
class Player(Base):
|
|
||||||
__tablename__ = 'player'
|
|
||||||
id = sa.Column(sa.Integer, autoincrement=True)
|
|
||||||
points = sa.Column(ScalarListType(int))
|
|
||||||
|
|
||||||
|
|
||||||
player = Player()
|
|
||||||
player.points = [11, 12, 8, 80]
|
|
||||||
session.commit()
|
|
||||||
|
|
||||||
|
.. autoclass:: ScalarListType
|
||||||
|
|
||||||
|
|
||||||
URLType
|
URLType
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
URLType stores furl_ objects into database.
|
.. module:: sqlalchemy_utils.types.url
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
from sqlalchemy_utils import URLType
|
|
||||||
from furl import furl
|
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
|
||||||
__tablename__ = 'user'
|
|
||||||
|
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
|
||||||
website = sa.Column(URLType)
|
|
||||||
|
|
||||||
|
|
||||||
user = User(website=u'www.example.com')
|
|
||||||
|
|
||||||
# website is coerced to furl object, hence all nice furl operations come
|
|
||||||
# available
|
|
||||||
user.website.args['some_argument'] = '12'
|
|
||||||
|
|
||||||
print user.website
|
|
||||||
# www.example.com?some_argument=12
|
|
||||||
|
|
||||||
|
.. autoclass:: URLType
|
||||||
|
|
||||||
|
|
||||||
UUIDType
|
UUIDType
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
UUIDType will store a UUID in the database in a native format, if available,
|
|
||||||
or a 16-byte BINARY column or a 32-character CHAR column if not.
|
|
||||||
|
|
||||||
::
|
.. module:: sqlalchemy_utils.types.uuid
|
||||||
|
|
||||||
from sqlalchemy_utils import UUIDType
|
.. autoclass:: UUIDType
|
||||||
import uuid
|
|
||||||
|
|
||||||
class User(Base):
|
|
||||||
__tablename__ = 'user'
|
|
||||||
|
|
||||||
# Pass `binary=False` to fallback to CHAR instead of BINARY
|
|
||||||
id = sa.Column(UUIDType(binary=False), primary_key=True)
|
|
||||||
|
|
||||||
|
|
||||||
TimezoneType
|
TimezoneType
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
TimezoneType provides a way for saving timezones (from either the pytz or the dateutil package) objects into database.
|
|
||||||
TimezoneType saves timezone objects as strings on the way in and converts them back to objects when querying the database.
|
|
||||||
|
|
||||||
|
.. module:: sqlalchemy_utils.types.timezone
|
||||||
|
|
||||||
::
|
.. autoclass:: TimezoneType
|
||||||
|
|
||||||
from sqlalchemy_utils import UUIDType
|
|
||||||
|
|
||||||
class User(Base):
|
|
||||||
__tablename__ = 'user'
|
|
||||||
|
|
||||||
# Pass backend='pytz' to change it to use pytz (dateutil by default)
|
|
||||||
timezone = sa.Column(TimezoneType(backend='pytz'))
|
|
||||||
|
|
||||||
|
|
||||||
The generates decorator
|
The generates decorator
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
Many times you may have generated property values. Usual cases include slugs from names or resized thumbnails from images.
|
.. module:: sqlalchemy_utils.decorators
|
||||||
|
|
||||||
SQLAlchemy-Utils provides a way to do this easily with `generates` decorator:
|
.. autofunction:: generates
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
class Article(self.Base):
|
|
||||||
__tablename__ = 'article'
|
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
|
||||||
name = sa.Column(sa.Unicode(255))
|
|
||||||
slug = sa.Column(sa.Unicode(255))
|
|
||||||
|
|
||||||
@generates(slug)
|
|
||||||
def _create_slug(self):
|
|
||||||
return self.name.lower().replace(' ', '-')
|
|
||||||
|
|
||||||
|
|
||||||
article = self.Article()
|
|
||||||
article.name = u'some article name'
|
|
||||||
self.session.add(article)
|
|
||||||
self.session.flush()
|
|
||||||
assert article.slug == u'some-article-name'
|
|
||||||
|
|
||||||
|
|
||||||
You can also pass the attribute name as a string argument for `generates`:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
class Article(self.Base):
|
|
||||||
...
|
|
||||||
|
|
||||||
@generates('slug')
|
|
||||||
def _create_slug(self):
|
|
||||||
return self.name.lower().replace(' ', '-')
|
|
||||||
|
|
||||||
|
|
||||||
These property generators can even be defined outside classes:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
class Article(self.Base):
|
|
||||||
__tablename__ = 'article'
|
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
|
||||||
name = sa.Column(sa.Unicode(255))
|
|
||||||
slug = sa.Column(sa.Unicode(255))
|
|
||||||
|
|
||||||
|
|
||||||
@generates(Article.slug)
|
|
||||||
def _create_article_slug(self):
|
|
||||||
return self.name.lower().replace(' ', '-')
|
|
||||||
|
|
||||||
|
|
||||||
Or with lazy evaluated string argument:
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
|
|
||||||
@generates('Article.slug')
|
|
||||||
def _create_article_slug(self):
|
|
||||||
return self.name.lower().replace(' ', '-')
|
|
||||||
|
|
||||||
|
|
||||||
Generic Relationship
|
Generic Relationship
|
||||||
@@ -478,10 +188,6 @@ Generic relationship is a form of relationship that supports creating a 1 to man
|
|||||||
# Find any events that are bound to users.
|
# Find any events that are bound to users.
|
||||||
session.query(Event).filter(Event.object.is_type(User)).all()
|
session.query(Event).filter(Event.object.is_type(User)).all()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _Babel: http://babel.pocoo.org/
|
|
||||||
.. _furl: https://github.com/gruns/furl
|
|
||||||
.. _colour: https://github.com/vaab/colour
|
.. _colour: https://github.com/vaab/colour
|
||||||
|
|
||||||
|
|
||||||
|
@@ -8,6 +8,73 @@ listeners_registered = False
|
|||||||
|
|
||||||
|
|
||||||
def generates(attr):
|
def generates(attr):
|
||||||
|
"""
|
||||||
|
Many times you may have generated property values. Usual cases include
|
||||||
|
slugs from names or resized thumbnails from images.
|
||||||
|
|
||||||
|
SQLAlchemy-Utils provides a way to do this easily with `generates`
|
||||||
|
decorator:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
class Article(self.Base):
|
||||||
|
__tablename__ = 'article'
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
name = sa.Column(sa.Unicode(255))
|
||||||
|
slug = sa.Column(sa.Unicode(255))
|
||||||
|
|
||||||
|
@generates(slug)
|
||||||
|
def _create_slug(self):
|
||||||
|
return self.name.lower().replace(' ', '-')
|
||||||
|
|
||||||
|
|
||||||
|
article = self.Article()
|
||||||
|
article.name = u'some article name'
|
||||||
|
self.session.add(article)
|
||||||
|
self.session.flush()
|
||||||
|
assert article.slug == u'some-article-name'
|
||||||
|
|
||||||
|
|
||||||
|
You can also pass the attribute name as a string argument for `generates`:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
class Article(self.Base):
|
||||||
|
...
|
||||||
|
|
||||||
|
@generates('slug')
|
||||||
|
def _create_slug(self):
|
||||||
|
return self.name.lower().replace(' ', '-')
|
||||||
|
|
||||||
|
|
||||||
|
These property generators can even be defined outside classes:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
class Article(self.Base):
|
||||||
|
__tablename__ = 'article'
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
name = sa.Column(sa.Unicode(255))
|
||||||
|
slug = sa.Column(sa.Unicode(255))
|
||||||
|
|
||||||
|
|
||||||
|
@generates(Article.slug)
|
||||||
|
def _create_article_slug(self):
|
||||||
|
return self.name.lower().replace(' ', '-')
|
||||||
|
|
||||||
|
|
||||||
|
Or with lazy evaluated string argument:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
@generates('Article.slug')
|
||||||
|
def _create_article_slug(self):
|
||||||
|
return self.name.lower().replace(' ', '-')
|
||||||
|
"""
|
||||||
|
|
||||||
register_listeners()
|
register_listeners()
|
||||||
|
|
||||||
def wraps(func):
|
def wraps(func):
|
||||||
|
@@ -28,6 +28,57 @@ class Choice(object):
|
|||||||
|
|
||||||
|
|
||||||
class ChoiceType(types.TypeDecorator, ScalarCoercible):
|
class ChoiceType(types.TypeDecorator, ScalarCoercible):
|
||||||
|
"""
|
||||||
|
ChoiceType offers way of having fixed set of choices for given column.
|
||||||
|
Columns with ChoiceTypes are automatically coerced to Choice objects.
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
class User(self.Base):
|
||||||
|
TYPES = [
|
||||||
|
(u'admin', u'Admin'),
|
||||||
|
(u'regular-user', u'Regular user')
|
||||||
|
]
|
||||||
|
|
||||||
|
__tablename__ = 'user'
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
name = sa.Column(sa.Unicode(255))
|
||||||
|
type = sa.Column(ChoiceType(TYPES))
|
||||||
|
|
||||||
|
|
||||||
|
user = User(type=u'admin')
|
||||||
|
user.type # Choice(type='admin', value=u'Admin')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ChoiceType is very useful when the rendered values change based on user's
|
||||||
|
locale:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from babel import lazy_gettext as _
|
||||||
|
|
||||||
|
|
||||||
|
class User(self.Base):
|
||||||
|
TYPES = [
|
||||||
|
(u'admin', _(u'Admin')),
|
||||||
|
(u'regular-user', _(u'Regular user'))
|
||||||
|
]
|
||||||
|
|
||||||
|
__tablename__ = 'user'
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
name = sa.Column(sa.Unicode(255))
|
||||||
|
type = sa.Column(ChoiceType(TYPES))
|
||||||
|
|
||||||
|
|
||||||
|
user = User(type=u'admin')
|
||||||
|
user.type # Choice(type='admin', value=u'Admin')
|
||||||
|
|
||||||
|
print user.type # u'Admin'
|
||||||
|
"""
|
||||||
|
|
||||||
impl = types.Unicode(255)
|
impl = types.Unicode(255)
|
||||||
|
|
||||||
def __init__(self, choices, impl=None):
|
def __init__(self, choices, impl=None):
|
||||||
|
@@ -12,8 +12,41 @@ except ImportError:
|
|||||||
|
|
||||||
class ColorType(types.TypeDecorator, ScalarCoercible):
|
class ColorType(types.TypeDecorator, ScalarCoercible):
|
||||||
"""
|
"""
|
||||||
Changes Color objects to a string representation on the way in and
|
ColorType provides a way for saving Color (from colour_ package) objects
|
||||||
changes them back to Color objects on the way out.
|
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__ = 'document'
|
||||||
|
id = sa.Column(sa.Integer, autoincrement=True)
|
||||||
|
name = sa.Column(sa.Unicode(50))
|
||||||
|
background_color = sa.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
|
||||||
"""
|
"""
|
||||||
STORE_FORMAT = u'hex'
|
STORE_FORMAT = u'hex'
|
||||||
impl = types.Unicode(20)
|
impl = types.Unicode(20)
|
||||||
|
@@ -23,8 +23,32 @@ ischema_names['json'] = PostgresJSONType
|
|||||||
|
|
||||||
|
|
||||||
class JSONType(sa.types.TypeDecorator):
|
class JSONType(sa.types.TypeDecorator):
|
||||||
"Represents an immutable structure as a json-encoded string."
|
"""
|
||||||
|
JSONType offers way of saving JSON data structures to database. On
|
||||||
|
PostgreSQL the underlying implementation of this data type is 'json' while
|
||||||
|
on other databases its simply 'text'.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy_utils import JSONType
|
||||||
|
|
||||||
|
|
||||||
|
class Product(Base):
|
||||||
|
__tablename__ = 'product'
|
||||||
|
id = sa.Column(sa.Integer, autoincrement=True)
|
||||||
|
name = sa.Column(sa.Unicode(50))
|
||||||
|
details = sa.Column(JSONType)
|
||||||
|
|
||||||
|
|
||||||
|
product = Product()
|
||||||
|
product.details = {
|
||||||
|
'color': 'red',
|
||||||
|
'type': 'car',
|
||||||
|
'max-speed': '400 mph'
|
||||||
|
}
|
||||||
|
session.commit()
|
||||||
|
"""
|
||||||
impl = sa.UnicodeText
|
impl = sa.UnicodeText
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@@ -11,8 +11,40 @@ except ImportError:
|
|||||||
|
|
||||||
class LocaleType(types.TypeDecorator, ScalarCoercible):
|
class LocaleType(types.TypeDecorator, ScalarCoercible):
|
||||||
"""
|
"""
|
||||||
Changes babel.Locale objects to a string representation on the way in and
|
LocaleType saves Babel_ Locale objects into database. The Locale objects
|
||||||
changes them back to Locale objects on the way out.
|
are converted to string on the way in and back to object on the way out.
|
||||||
|
|
||||||
|
In order to use LocaleType you need to install Babel_ first.
|
||||||
|
|
||||||
|
.. _Babel: http://babel.pocoo.org/
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy_utils import LocaleType
|
||||||
|
from babel import Locale
|
||||||
|
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
id = sa.Column(sa.Integer, autoincrement=True)
|
||||||
|
name = sa.Column(sa.Unicode(50))
|
||||||
|
locale = sa.Column(LocaleType)
|
||||||
|
|
||||||
|
|
||||||
|
user = User()
|
||||||
|
user.locale = Locale('en_US')
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
Like many other types this type also supports scalar coercion:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
user.locale = 'de_DE'
|
||||||
|
user.locale # Locale('de_DE')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
impl = types.Unicode(10)
|
impl = types.Unicode(10)
|
||||||
|
@@ -12,6 +12,48 @@ class NumberRangeRawType(types.UserDefinedType):
|
|||||||
|
|
||||||
|
|
||||||
class NumberRangeType(types.TypeDecorator, ScalarCoercible):
|
class NumberRangeType(types.TypeDecorator, ScalarCoercible):
|
||||||
|
"""
|
||||||
|
NumberRangeType provides way for saving range of numbers into database.
|
||||||
|
|
||||||
|
Example ::
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy_utils import NumberRangeType, NumberRange
|
||||||
|
|
||||||
|
|
||||||
|
class Event(Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
id = sa.Column(sa.Integer, autoincrement=True)
|
||||||
|
name = sa.Column(sa.Unicode(255))
|
||||||
|
estimated_number_of_persons = sa.Column(NumberRangeType)
|
||||||
|
|
||||||
|
|
||||||
|
party = Event(name=u'party')
|
||||||
|
|
||||||
|
# we estimate the party to contain minium of 10 persons and at max
|
||||||
|
# 100 persons
|
||||||
|
party.estimated_number_of_persons = NumberRange(10, 100)
|
||||||
|
|
||||||
|
print party.estimated_number_of_persons
|
||||||
|
# '10-100'
|
||||||
|
|
||||||
|
|
||||||
|
NumberRange supports some arithmetic operators:
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
meeting = Event(name=u'meeting')
|
||||||
|
|
||||||
|
meeting.estimated_number_of_persons = NumberRange(20, 40)
|
||||||
|
|
||||||
|
total = (
|
||||||
|
meeting.estimated_number_of_persons +
|
||||||
|
party.estimated_number_of_persons
|
||||||
|
)
|
||||||
|
print total
|
||||||
|
# '30-140'
|
||||||
|
"""
|
||||||
|
|
||||||
impl = NumberRangeRawType
|
impl = NumberRangeRawType
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
|
@@ -8,6 +8,50 @@ class ScalarListException(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class ScalarListType(types.TypeDecorator):
|
class ScalarListType(types.TypeDecorator):
|
||||||
|
"""
|
||||||
|
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 ScalarListType
|
||||||
|
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
id = sa.Column(sa.Integer, autoincrement=True)
|
||||||
|
hobbies = sa.Column(ScalarListType())
|
||||||
|
|
||||||
|
|
||||||
|
user = User()
|
||||||
|
user.hobbies = [u'football', u'ice_hockey']
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
You can easily set up integer lists too:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy_utils import ScalarListType
|
||||||
|
|
||||||
|
|
||||||
|
class Player(Base):
|
||||||
|
__tablename__ = 'player'
|
||||||
|
id = sa.Column(sa.Integer, autoincrement=True)
|
||||||
|
points = sa.Column(ScalarListType(int))
|
||||||
|
|
||||||
|
|
||||||
|
player = Player()
|
||||||
|
player.points = [11, 12, 8, 80]
|
||||||
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
impl = sa.UnicodeText()
|
impl = sa.UnicodeText()
|
||||||
|
|
||||||
def __init__(self, coerce_func=six.text_type, separator=u','):
|
def __init__(self, coerce_func=six.text_type, separator=u','):
|
||||||
|
@@ -6,8 +6,21 @@ from .scalar_coercible import ScalarCoercible
|
|||||||
|
|
||||||
class TimezoneType(types.TypeDecorator, ScalarCoercible):
|
class TimezoneType(types.TypeDecorator, ScalarCoercible):
|
||||||
"""
|
"""
|
||||||
Changes Timezone objects to a string representation on the way in and
|
TimezoneType provides a way for saving timezones (from either the pytz or
|
||||||
changes them back to Timezone objects on the way out.
|
the dateutil package) objects into database. TimezoneType saves timezone
|
||||||
|
objects as strings on the way in and converts them back to objects when
|
||||||
|
querying the database.
|
||||||
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from sqlalchemy_utils import TimezoneType
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
|
||||||
|
# Pass backend='pytz' to change it to use pytz (dateutil by default)
|
||||||
|
timezone = sa.Column(TimezoneType(backend='pytz'))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
impl = types.CHAR(50)
|
impl = types.CHAR(50)
|
||||||
|
@@ -9,6 +9,34 @@ from .scalar_coercible import ScalarCoercible
|
|||||||
|
|
||||||
|
|
||||||
class URLType(types.TypeDecorator, ScalarCoercible):
|
class URLType(types.TypeDecorator, ScalarCoercible):
|
||||||
|
"""
|
||||||
|
URLType stores furl_ objects into database.
|
||||||
|
|
||||||
|
.. _furl: https://github.com/gruns/furl
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from sqlalchemy_utils import URLType
|
||||||
|
from furl import furl
|
||||||
|
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
|
||||||
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
website = sa.Column(URLType)
|
||||||
|
|
||||||
|
|
||||||
|
user = User(website=u'www.example.com')
|
||||||
|
|
||||||
|
# website is coerced to furl object, hence all nice furl operations come
|
||||||
|
# available
|
||||||
|
user.website.args['some_argument'] = '12'
|
||||||
|
|
||||||
|
print user.website
|
||||||
|
# www.example.com?some_argument=12
|
||||||
|
"""
|
||||||
|
|
||||||
impl = types.UnicodeText
|
impl = types.UnicodeText
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
|
@@ -9,8 +9,18 @@ class UUIDType(types.TypeDecorator, ScalarCoercible):
|
|||||||
"""
|
"""
|
||||||
Stores a UUID in the database natively when it can and falls back to
|
Stores a UUID in the database natively when it can and falls back to
|
||||||
a BINARY(16) or a CHAR(32) when it can't.
|
a BINARY(16) or a CHAR(32) when it can't.
|
||||||
"""
|
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
from sqlalchemy_utils import UUIDType
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
class User(Base):
|
||||||
|
__tablename__ = 'user'
|
||||||
|
|
||||||
|
# Pass `binary=False` to fallback to CHAR instead of BINARY
|
||||||
|
id = sa.Column(UUIDType(binary=False), primary_key=True)
|
||||||
|
"""
|
||||||
impl = types.BINARY(16)
|
impl = types.BINARY(16)
|
||||||
|
|
||||||
python_type = uuid.UUID
|
python_type = uuid.UUID
|
||||||
|
Reference in New Issue
Block a user