Alex Alifimoff Alex Alifimoff - 3 months ago 32
Python Question

SQLAlchemy column with enum using PEP 435 compliant enum produces table creation error

I have an enum... defined very similarly to here.

When I try to create a table using the enum, as in the example, I get an error during table creation. It is a very vague error. Here is code that replicates the problem:

from sqlalchemy import Table, MetaData, Column, Enum, create_engine
import enum
class myEnum(enum.Enum):
one = 'one'
two = 'two'
three = 'three'

def main():
e = create_engine('sqlite:///:memory:')
e.echo = True
m = MetaData(bind = e)
t = Table('table', m, Column('my_enum', Enum(myEnum)))
t.create()
if __name__ == '__main__': main()


I get an
AttributeError: replace
when I run this code, with a seemingly useless stacktrace. I honestly don't even know where to begin debugging this and while I can conceive of a couple of possible workarounds, I am relatively new to SQLAlchemy so I'm not sure what the cleanest solution is. Surely basic enum support is a relatively simple expectation of a ORM framework?

Here is the full stack trace:

Traceback (most recent call last):
File "table_test.py", line 17, in <module>
if __name__ == '__main__': main()
File "table_test.py", line 16, in main
t.create()
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\schema.py", line 725, in create
checkfirst=checkfirst)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1856, in _run_visitor
conn._run_visitor(visitorcallable, element, **kwargs)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1481, in _run_visitor
**kwargs).traverse_single(element)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 121, in traverse_single
return meth(obj, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\ddl.py", line 764, in visit_table
include_foreign_key_constraints=include_foreign_key_constraints
File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 914, in execute
return meth(self, multiparams, params)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\ddl.py", line 68, in _execute_on_connection
return connection._execute_ddl(self, multiparams, params)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 962, in _execute_ddl
compiled = ddl.compile(dialect=dialect)
File "<string>", line 1, in <lambda>
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 494, in compile
return self._compiler(dialect, bind=bind, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\ddl.py", line 26, in _compiler
return dialect.ddl_compiler(dialect, self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 190, in __init__
self.string = self.process(self.statement, **compile_kwargs)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 213, in process
return obj._compiler_dispatch(self, **kwargs)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
return meth(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 2173, in visit_create_table
create.include_foreign_key_constraints)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 2220, in create_table_constraints
for constraint in constraints
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 2218, in <genexpr>
p for p in
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 2226, in <genexpr>
not getattr(constraint, 'use_alter', False)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 213, in process
return obj._compiler_dispatch(self, **kwargs)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 93, in _compiler_dispatch
return meth(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 2369, in visit_check_constraint
literal_binds=True)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 213, in process
return obj._compiler_dispatch(self, **kwargs)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
return meth(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 927, in visit_binary
return self._generate_generic_binary(binary, opstring, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 944, in _generate_generic_binary
binary.right._compiler_dispatch(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
return meth(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 527, in visit_grouping
return "(" + grouping.element._compiler_dispatch(self, **kwargs) + ")"
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
return meth(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 751, in visit_clauselist
for c in clauselist.clauses)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 748, in <genexpr>
s for s in
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 751, in <genexpr>
for c in clauselist.clauses)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\visitors.py", line 81, in _compiler_dispatch
return meth(self, **kw)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1071, in visit_bindparam
bindparam, within_columns_clause=True, **kwargs)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1103, in render_literal_bindparam
return self.render_literal_value(value, bindparam.type)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\compiler.py", line 1118, in render_literal_value
return processor(value)
File "C:\Anaconda3\lib\site-packages\sqlalchemy\sql\sqltypes.py", line 171, in process
value = value.replace("'", "''")
File "C:\Anaconda3\lib\enum.py", line 268, in __getattr__
raise AttributeError(name) from None
AttributeError: replace

Answer

PEP-435 enum support is being added in 1.1.

1.1.0b1 was recently released. You can upgrade to 1.1.0b1 but be wary of bugs. Based on release history I would say the stable version should be released in a month or two.

how to upgrade:

pip install 'sqlalchemy==1.1.0b3'