Alembic not handling column_types.PasswordType : Flask+SQLAlchemy+Alembic
<p><strong>Background</strong></p>

<p>I'm trying to use a PostgreSQL back-end instead of Sqlite in this <a href="https://github.com/frol/flask-restplus-server-example" rel="nofollow">Flask + RESTplus server example</a>.</p>

<p>I faced an issue with the PasswordType db column type. In order to make it work, I had to change the following code in <a href="https://github.com/frol/flask-restplus-server-example/blob/master/app/modules/users/models.py#L46" rel="nofollow">app/modules/users/models.py</a></p>

<pre><code>password = db.Column(
    column_types.PasswordType(
        max_length=128,
        schemes=('bcrypt', )
    ),
    nullable=False
)
</code></pre>

<p>to </p>

<pre><code>password = db.Column(db.String(length=128), nullable=False)
</code></pre>

<p>which is really bad as passwords will be stored in clear text... and I need your help!</p>

<p>After changing the <a href="https://github.com/frol/flask-restplus-server-example/blob/master/tasks/app/db_templates/flask/script.py.mako#L13-15" rel="nofollow">line 13 to 15 in tasks/app/db_templates/flask/script.py.mako
</a> to </p>

<pre><code>from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils
${imports if imports else ""}
</code></pre>

<p>I get the following error message, apparently related to passlib:</p>

<pre><code>2016-08-31 23:18:52,751 [INFO] [alembic.runtime.migration] Context impl PostgresqlImpl.
2016-08-31 23:18:52,752 [INFO] [alembic.runtime.migration] Will assume transactional DDL.
2016-08-31 23:18:52,759 [INFO] [alembic.runtime.migration] Running upgrade  -&gt; 99b329343a41, empty message
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/type_api.py", line 359, in dialect_impl
    return dialect._type_memos[self]['impl']
  File "/usr/local/lib/python3.5/weakref.py", line 365, in __getitem__
    return self.data[ref(key)]
KeyError: &lt;weakref at 0x7fde70d524a8; to 'PasswordType' at 0x7fde70a840b8&gt;

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/invoke", line 11, in &lt;module&gt;
    sys.exit(program.run())
  File "/usr/local/lib/python3.5/site-packages/invoke/program.py", line 270, in run
    self.execute()
  File "/usr/local/lib/python3.5/site-packages/invoke/program.py", line 381, in execute
    executor.execute(*self.tasks)
  File "/usr/local/lib/python3.5/site-packages/invoke/executor.py", line 113, in execute
    result = call.task(*args, **call.kwargs)
  File "/usr/local/lib/python3.5/site-packages/invoke/tasks.py", line 111, in __call__
    result = self.body(*args, **kwargs)
  File "/usr/src/app/tasks/app/run.py", line 35, in run
    context.invoke_execute(context, 'app.db.upgrade')
  File "/usr/src/app/tasks/__init__.py", line 72, in invoke_execute
    results = Executor(namespace, config=context.config).execute((command_name, kwargs))
  File "/usr/local/lib/python3.5/site-packages/invoke/executor.py", line 113, in execute
    result = call.task(*args, **call.kwargs)
  File "/usr/local/lib/python3.5/site-packages/invoke/tasks.py", line 111, in __call__
    result = self.body(*args, **kwargs)
  File "/usr/src/app/tasks/app/db.py", line 177, in upgrade
    command.upgrade(config, revision, sql=sql, tag=tag)
  File "/usr/local/lib/python3.5/site-packages/alembic/command.py", line 174, in upgrade
    script.run_env()
  File "/usr/local/lib/python3.5/site-packages/alembic/script/base.py", line 407, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "/usr/local/lib/python3.5/site-packages/alembic/util/pyfiles.py", line 93, in load_python_file
    module = load_module_py(module_id, path)
  File "/usr/local/lib/python3.5/site-packages/alembic/util/compat.py", line 68, in load_module_py
    module_id, path).load_module(module_id)
  File "&lt;frozen importlib._bootstrap_external&gt;", line 385, in _check_name_wrapper
  File "&lt;frozen importlib._bootstrap_external&gt;", line 806, in load_module
  File "&lt;frozen importlib._bootstrap_external&gt;", line 665, in load_module
  File "&lt;frozen importlib._bootstrap&gt;", line 268, in _load_module_shim
  File "&lt;frozen importlib._bootstrap&gt;", line 693, in _load
  File "&lt;frozen importlib._bootstrap&gt;", line 673, in _load_unlocked
  File "&lt;frozen importlib._bootstrap_external&gt;", line 662, in exec_module
  File "&lt;frozen importlib._bootstrap&gt;", line 222, in _call_with_frames_removed
  File "migrations/env.py", line 93, in &lt;module&gt;
    run_migrations_online()
  File "migrations/env.py", line 86, in run_migrations_online
    context.run_migrations()
  File "&lt;string&gt;", line 8, in run_migrations
  File "/usr/local/lib/python3.5/site-packages/alembic/runtime/environment.py", line 797, in run_migrations
    self.get_context().run_migrations(**kw)
  File "/usr/local/lib/python3.5/site-packages/alembic/runtime/migration.py", line 312, in run_migrations
    step.migration_fn(**kw)
  File "/usr/src/app/migrations/versions/99b329343a41_.py", line 47, in upgrade
    sa.UniqueConstraint('username')
  File "&lt;string&gt;", line 8, in create_table
  File "&lt;string&gt;", line 3, in create_table
  File "/usr/local/lib/python3.5/site-packages/alembic/operations/ops.py", line 1098, in create_table
    return operations.invoke(op)
  File "/usr/local/lib/python3.5/site-packages/alembic/operations/base.py", line 318, in invoke
    return fn(self, operation)
  File "/usr/local/lib/python3.5/site-packages/alembic/operations/toimpl.py", line 101, in create_table
    operations.impl.create_table(table)
  File "/usr/local/lib/python3.5/site-packages/alembic/ddl/impl.py", line 194, in create_table
    self._exec(schema.CreateTable(table))
  File "/usr/local/lib/python3.5/site-packages/alembic/ddl/impl.py", line 118, in _exec
    return conn.execute(construct, *multiparams, **params)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 914, in execute
    return meth(self, multiparams, params)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/ddl.py", line 68, in _execute_on_connection
    return connection._execute_ddl(self, multiparams, params)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 962, in _execute_ddl
    compiled = ddl.compile(dialect=dialect)
  File "&lt;string&gt;", line 1, in &lt;lambda&gt;
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/elements.py", line 494, in compile
    return self._compiler(dialect, bind=bind, **kw)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/ddl.py", line 26, in _compiler
    return dialect.ddl_compiler(dialect, self, **kw)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/compiler.py", line 190, in __init__
    self.string = self.process(self.statement, **compile_kwargs)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/compiler.py", line 213, in process
    return obj._compiler_dispatch(self, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/visitors.py", line 81, in _compiler_dispatch
    return meth(self, **kw)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/compiler.py", line 2157, in visit_create_table
    and not first_pk)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/compiler.py", line 213, in process
    return obj._compiler_dispatch(self, **kwargs)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/visitors.py", line 81, in _compiler_dispatch
    return meth(self, **kw)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/compiler.py", line 2188, in visit_create_column
    first_pk=first_pk
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/dialects/postgresql/base.py", line 1580, in get_column_specification
    impl_type = column.type.dialect_impl(self.dialect)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/type_api.py", line 361, in dialect_impl
    return self._dialect_info(dialect)['impl']
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/type_api.py", line 403, in _dialect_info
    impl = self._gen_dialect_impl(dialect)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy/sql/type_api.py", line 763, in _gen_dialect_impl
    typedesc = self.load_dialect_impl(dialect).dialect_impl(dialect)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy_utils/types/password.py", line 194, in load_dialect_impl
    impl = postgresql.BYTEA(self.length)
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy_utils/types/password.py", line 168, in length
    self._max_length = self.calculate_max_length()
  File "/usr/local/lib/python3.5/site-packages/sqlalchemy_utils/types/password.py", line 176, in calculate_max_length
    for name in self.context.schemes():
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 2714, in __getattribute__
    self._lazy_init()
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 2708, in _lazy_init
    super(LazyCryptContext, self).__init__(**kwds)
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 1707, in __init__
    self.load(kwds)
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 1896, in load
    config = _CryptConfig(source)
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 1019, in __init__
    self._init_options(source)
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 1097, in _init_options
    key, value = norm_context_option(key, value)
  File "/usr/local/lib/python3.5/site-packages/passlib/context.py", line 1162, in _norm_context_option
    raise KeyError("unknown CryptContext keyword: %r" % (key,))
KeyError: "unknown CryptContext keyword: 'length'"
</code></pre>

<p>Any idea? Thanks in advance for your help!</p>

<p>I see that you are having a new migration <code>99b329343a41_.py</code> (it doesn't exist in my Flask-RESTplus-example-server). Please, review your new migration and <strong>remove</strong> everything related to PasswordType. It is a bug in SQLAlchemy-Utils, which doesn't play nice with Alembic: <a href="https://github.com/kvesteri/sqlalchemy-utils/issues/106" rel="nofollow">https://github.com/kvesteri/sqlalchemy-utils/issues/106</a></p>

python postgresql flask-sqlalchemy alembic passlib