Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EUIType #763

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sqlalchemy_utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
EncryptedType,
EnrichedDateTimeType,
EnrichedDateType,
EUIType,
instrumented_list,
InstrumentedList,
Int8RangeType,
Expand Down
1 change: 1 addition & 0 deletions sqlalchemy_utils/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
)
from .enriched_datetime.enriched_date_type import EnrichedDateType # noqa
from .ip_address import IPAddressType # noqa
from .eui import EUIType
from .json import JSONType # noqa
from .locale import LocaleType # noqa
from .ltree import LtreeType # noqa
Expand Down
76 changes: 76 additions & 0 deletions sqlalchemy_utils/types/eui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from typing import Any, Type

from sqlalchemy import types
from ..exceptions import ImproperlyConfigured
from .scalar_coercible import ScalarCoercible

eui = None
try:
from netaddr import EUI
python_eui_type = EUI
except (ImportError, AttributeError):
python_eui_type = None


class EUIType(ScalarCoercible, types.TypeDecorator):
"""

EUIType provides a way for saving EUI (from netaddr package) objects
into database. EUIType saves EUI objects as strings on the way in
and converts them back to objects when querying the database.

EUI objects can store either EUI64 identifiers or EUI48 identifiers
EUI48 is frequently used for network MAC addresses.

::

from netaddr import EUI
from sqlalchemy_utils import EUI


class Interface(Base):
__tablename__ = 'interface'
id = sa.Column(sa.Integer, autoincrement=True)
name = sa.Column(sa.Unicode(50))
mac_address = sa.Column(EUIType)

intf = Interface()
intf.mac_address = EUI('a1:b2:c3:d4:e5:f6')
session.commit()


Querying the database returns EUI objects:

::

import netaddr

intf = session.query(Interface).first()

intf.mac_address.dialect = netaddr.mac_unix
intf.mac_address
# 'a1:b2:c3:d4:e5:f6'

.. _netaddr: https://github.com/netaddr/netaddr
"""

impl = types.Unicode(50)
cache_ok = True

def __init__(self, max_length=50, *args, **kwargs):
super().__init__(*args, **kwargs)
self.impl = types.Unicode(max_length)


def process_bind_param(selfself, value, dialect):
return str(value) if value else None

def process_result_value(selfself, value, dialect):
return EUI(value) if value else None

def _coerce(self, value):
return EUI(value) if value else None

@property
def python_type(self):
return self.impl.type.python_type