Discussion:
Hacky fix I had to put in to get Alembic to work with custom type decorators
j***@360pi.com
2014-01-30 18:28:50 UTC
Permalink
I'm wondering if there is a better way of getting around an issue I ran
into with Alembic, what I did is below.

I have models which have custom type decorators, when I ran alembic it
complained that SafeGuid wasn't on the model. I found a post from someone
that said the only way around this was to redirect to the types directly in
SqlAlchemy like below. Any ideas if there is a cleaner way?


env.py

from myproj.typedecorators import (
SafeGuid, Upc, SafeDecimal, SafeKeyValuePropertyBag, SafeBigInteger)

# this is to get around an issue in SqlAlchemy where it looks for the
# type decorators on the model. We are just redirecting to the real
# implementation of the decorator here.
import sqlalchemy as sa
sa.SafeGuid = SafeGuid
sa.Upc = Upc
sa.SafeDecimal = SafeDecimal
sa.SafeKeyValuePropertyBag = SafeKeyValuePropertyBag
sa.SafeBigInteger = SafeBigInteger
--
You received this message because you are subscribed to the Google Groups "sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy-alembic+***@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
Michael Bayer
2014-01-30 21:03:25 UTC
Permalink
I'm wondering if there is a better way of getting around an issue I ran into with Alembic, what I did is below.
I have models which have custom type decorators, when I ran alembic it complained that SafeGuid wasn't on the model. I found a post from someone that said the only way around this was to redirect to the types directly in SqlAlchemy like below. Any ideas if there is a cleaner way?
env.py
from myproj.typedecorators import (
SafeGuid, Upc, SafeDecimal, SafeKeyValuePropertyBag, SafeBigInteger)
# this is to get around an issue in SqlAlchemy where it looks for the
# type decorators on the model. We are just redirecting to the real
# implementation of the decorator here.
import sqlalchemy as sa
sa.SafeGuid = SafeGuid
sa.Upc = Upc
sa.SafeDecimal = SafeDecimal
sa.SafeKeyValuePropertyBag = SafeKeyValuePropertyBag
sa.SafeBigInteger = SafeBigInteger
sorry, this is really not correct at all (and if this on stackoverflow, point me there so I can make sure people don’t start doing this).

first of all, you don’t actually need TypeDecorators in an Alembic migration script. the purpose of a TypeDecorator is to define Python-side behavior when you are emitting SQL expressions such as INSERT and SELECT. The migrations generated by Alembic are only CREATE TABLE and ALTER COLUMN statements; there are no Python values being processed here. So if you for example had a TypeDecorator of an Integer, your migration script only needs “Integer” in it in any case.

Secondly, Alembic gives you *two* options to determine how a type object is rendered when using autogenerate. The first is to implement __repr__() on your type, however that won’t give you access to the parent module. The second is to implement render_item(), which gives you complete control over how any specific type is rendered. Implementing this will give you a way to fully control for any specific type how it is rendered. this is configurable via render_item: http://alembic.readthedocs.org/en/latest/api.html#alembic.environment.EnvironmentContext.configure.params.render_item

thirdly, the whole “sa.” prefix is configurable in any case. You should change this to be something like “myproject.types” or something like that; then within “types”, implement *every* data type your application uses, both those from SQLAlchemy as well as those that are custom. That way your application retains central control over all datatypes that are available. Or, you can set the prefix to None, and then modify your script.py.mako template to import all the types that your migration scripts might want to use. This prefix is configurable via sqlalchemy_module_prefix: http://alembic.readthedocs.org/en/latest/api.html#alembic.environment.EnvironmentContext.configure.params.sqlalchemy_module_prefix

I will add a ticket to remind me to document all of this.
--
You received this message because you are subscribed to the Google Groups "sqlalchemy-alembic" group.
For more options, visit https://groups.google.com/groups/opt_out.
Michael Bayer
2014-02-01 17:57:41 UTC
Permalink
I'm wondering if there is a better way of getting around an issue I ran into with Alembic, what I did is below.
I’ve updated the documentation and also added a new feature user_module_prefix in the upcoming 0.6.3 to address this specifically. See:

http://alembic.readthedocs.org/en/latest/tutorial.html#rendering-custom-types-in-autogenerate (note that these docs apply to 0.6.2 as well)

and

http://alembic.readthedocs.org/en/latest/tutorial.html#controlling-the-module-prefix (new feature in 0.6.3)
I have models which have custom type decorators, when I ran alembic it complained that SafeGuid wasn't on the model. I found a post from someone that said the only way around this was to redirect to the types directly in SqlAlchemy like below. Any ideas if there is a cleaner way?
env.py
from myproj.typedecorators import (
SafeGuid, Upc, SafeDecimal, SafeKeyValuePropertyBag, SafeBigInteger)
# this is to get around an issue in SqlAlchemy where it looks for the
# type decorators on the model. We are just redirecting to the real
# implementation of the decorator here.
import sqlalchemy as sa
sa.SafeGuid = SafeGuid
sa.Upc = Upc
sa.SafeDecimal = SafeDecimal
sa.SafeKeyValuePropertyBag = SafeKeyValuePropertyBag
sa.SafeBigInteger = SafeBigInteger
--
You received this message because you are subscribed to the Google Groups "sqlalchemy-alembic" group.
For more options, visit https://groups.google.com/groups/opt_out.
Loading...