From bd86059d69a00a5691edb6e00cf0f04028926c8b Mon Sep 17 00:00:00 2001 From: Vlad Frolov Date: Tue, 8 Nov 2016 23:06:52 +0200 Subject: [PATCH] Added SQLite support for PasswordType --- sqlalchemy_utils/types/password.py | 15 ++++++++------- tests/types/test_password.py | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/sqlalchemy_utils/types/password.py b/sqlalchemy_utils/types/password.py index 3114e99..c2fcdd1 100644 --- a/sqlalchemy_utils/types/password.py +++ b/sqlalchemy_utils/types/password.py @@ -2,7 +2,7 @@ import weakref import six from sqlalchemy import types -from sqlalchemy.dialects import oracle, postgresql +from sqlalchemy.dialects import oracle, postgresql, sqlite from sqlalchemy.ext.mutable import Mutable from ..exceptions import ImproperlyConfigured @@ -192,14 +192,15 @@ class PasswordType(types.TypeDecorator, ScalarCoercible): if dialect.name == 'postgresql': # Use a BYTEA type for postgresql. impl = postgresql.BYTEA(self.length) - return dialect.type_descriptor(impl) - if dialect.name == 'oracle': + elif dialect.name == 'oracle': # Use a RAW type for oracle. impl = oracle.RAW(self.length) - return dialect.type_descriptor(impl) - - # Use a VARBINARY for all other dialects. - impl = types.VARBINARY(self.length) + elif dialect.name == 'sqlite': + # Use a BLOB type for sqlite + impl = sqlite.BLOB(self.length) + else: + # Use a VARBINARY for all other dialects. + impl = types.VARBINARY(self.length) return dialect.type_descriptor(impl) def process_bind_param(self, value, dialect): diff --git a/tests/types/test_password.py b/tests/types/test_password.py index f26f8d7..eea3b32 100644 --- a/tests/types/test_password.py +++ b/tests/types/test_password.py @@ -1,6 +1,10 @@ import mock import pytest import sqlalchemy as sa +import sqlalchemy.dialects.mysql +import sqlalchemy.dialects.oracle +import sqlalchemy.dialects.postgresql +import sqlalchemy.dialects.sqlite from sqlalchemy import inspect from sqlalchemy_utils import Password, PasswordType, types # noqa @@ -52,6 +56,23 @@ def onload_callback(schemes, deprecated): @pytest.mark.skipif('types.password.passlib is None') class TestPasswordType(object): + @pytest.mark.parametrize('dialect_module,impl', [ + (sqlalchemy.dialects.sqlite, sa.dialects.sqlite.BLOB), + (sqlalchemy.dialects.postgresql, sa.dialects.postgresql.BYTEA), + (sqlalchemy.dialects.oracle, sa.dialects.oracle.RAW), + (sqlalchemy.dialects.mysql, sa.VARBINARY), + ]) + def test_load_dialect_impl(self, dialect_module, impl): + """ + Should produce the same impl type as Alembic would expect after + inspecing a database + """ + password_type = PasswordType() + assert isinstance( + password_type.load_dialect_impl(dialect_module.dialect()), + impl + ) + def test_encrypt(self, User): """Should encrypt the password on setting the attribute.""" obj = User()