1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
import six
from sqlalchemy import types
from sqlalchemy_utils.exceptions import ImproperlyConfigured
from .scalar_coercible import ScalarCoercible
ip_address = None
try:
from ipaddress import ip_address
except ImportError:
try:
from ipaddr import IPAddress as ip_address
except ImportError:
pass
class IPAddressType(types.TypeDecorator, ScalarCoercible):
"""
Changes IPAddress objects to a string representation on the way in and
changes them back to IPAddress objects on the way out.
IPAddressType uses ipaddress package on Python >= 3 and ipaddr_ package on
Python 2. In order to use IPAddressType with python you need to install
ipaddr_ first.
.. _ipaddr: https://pypi.python.org/pypi/ipaddr
::
from sqlalchemy_utils import IPAddressType
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, autoincrement=True)
name = sa.Column(sa.Unicode(255))
ip_address = sa.Column(IPAddressType)
user = User()
user.ip_address = '123.123.123.123'
session.add(user)
session.commit()
user.ip_address # IPAddress object
"""
impl = types.Unicode(50)
def __init__(self, max_length=50, *args, **kwargs):
if not ip_address:
raise ImproperlyConfigured(
"'ipaddr' package is required to use 'IPAddressType' "
"in python 2"
)
super(IPAddressType, self).__init__(*args, **kwargs)
self.impl = types.Unicode(max_length)
def process_bind_param(self, value, dialect):
return six.text_type(value) if value else None
def process_result_value(self, value, dialect):
return ip_address(value) if value else None
def _coerce(self, value):
return ip_address(value) if value else None
@property
def python_type(self):
return self.impl.type.python_type
|