Alembic not handling column_types.PasswordType : Flask+SQLAlchemy+Alembic
Question: **Background**

I'm trying to use a PostgreSQL back-end instead of Sqlite in this [Flask +
RESTplus server example](https://github.com/frol/flask-restplus-server-
example).

I faced an issue with the PasswordType db column type. In order to make it
work, I had to change the following code in
[app/modules/users/models.py](https://github.com/frol/flask-restplus-server-
example/blob/master/app/modules/users/models.py#L46)

    
    
    password = db.Column(
        column_types.PasswordType(
            max_length=128,
            schemes=('bcrypt', )
        ),
        nullable=False
    )
    

to

    
    
    password = db.Column(db.String(length=128), nullable=False)
    

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

After changing the [line 13 to 15 in
tasks/app/db_templates/flask/script.py.mako ](https://github.com/frol/flask-
restplus-server-
example/blob/master/tasks/app/db_templates/flask/script.py.mako#L13-15) to

    
    
    from alembic import op
    import sqlalchemy as sa
    import sqlalchemy_utils
    ${imports if imports else ""}
    

I get the following error message, apparently related to passlib:

    
    
    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  -> 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: <weakref at 0x7fde70d524a8; to 'PasswordType' at 0x7fde70a840b8>
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/local/bin/invoke", line 11, in <module>
        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 "<frozen importlib._bootstrap_external>", line 385, in _check_name_wrapper
      File "<frozen importlib._bootstrap_external>", line 806, in load_module
      File "<frozen importlib._bootstrap_external>", line 665, in load_module
      File "<frozen importlib._bootstrap>", line 268, in _load_module_shim
      File "<frozen importlib._bootstrap>", line 693, in _load
      File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 662, in exec_module
      File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
      File "migrations/env.py", line 93, in <module>
        run_migrations_online()
      File "migrations/env.py", line 86, in run_migrations_online
        context.run_migrations()
      File "<string>", 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 "<string>", line 8, in create_table
      File "<string>", 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 "<string>", line 1, in <lambda>
      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'"
    

Any idea? Thanks in advance for your help!


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

