alembic icon indicating copy to clipboard operation
alembic copied to clipboard

Autogenerate does not consider schema for enum type

Open renedupont opened this issue 3 years ago • 10 comments

Describe the bug I am using Postgres 12, Alembic (1.7.1) and SQLAlchemy (1.4.23) and have something like this SQLAlchemy enum in my model:

class MyEnum(enum.Enum):
    one= 'one'
    two= 'two'

...

my_enum = Column(Enum(MyEnum), nullable=False)

When I run alembic revision --autogenerate

I get in my migration script:

sa.Column('my_enum',
          sa.Enum('one', 'two', name='myenum'),
          nullable=False),

I am using another schema than the default (public) one and while there is a schema arg that can be set (and I am currently changing the script manually adding it), it is not being considered by autogenerate. For stuff like tables and so on, it works perfectly and the schema is considered.

Expected behavior I'd like to see the following being autogenerated for my example case:

sa.Column('my_enum',
          sa.Enum('one', 'two', name='myenum', schema='my_schema_name'), 
          nullable=False),

Versions.

  • OS: Ubuntu 20.04
  • Python: 3.8.10
  • Alembic: 1.7.1
  • SQLAlchemy: 1.4.23
  • Database: Postgres 12
  • DBAPI:

renedupont avatar Sep 06 '21 10:09 renedupont

Thanks for reporting.

I am using another schema than the default (public) one and while there is a schema arg that can be se

is the schema set on the MetaData?

CaselIT avatar Sep 06 '21 18:09 CaselIT

In env.py I have

from myapp.models import Base
... 
target_metadata = Base.metadata

and in myapp.models I do:

engine: Engine = create_engine(myDbUrl, pool_pre_ping=True)
db_session: scoped_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

renedupont avatar Sep 07 '21 07:09 renedupont

Where is the schema defined?

CaselIT avatar Sep 07 '21 07:09 CaselIT

In myapp.models I have a base model like this where I set the schema:

class BaseModel(Base):
    __abstract__ = True
    __table_args__ = {'extend_existing': True, 'schema': 'my_schema_name'}
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)

The model class that contains the enum in question is derived from this base model class.

renedupont avatar Sep 07 '21 08:09 renedupont

Looking at it again, I think I have to add more info of the scenario described in my opening post. The auto-generated full example looks actually more like this:

    op.create_table('my_table_name',
                              sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
                              sa.Column('my_enum',
                                                sa.Enum('one', 'two', name='myenum'), nullable=False),
                              sa.PrimaryKeyConstraint('id'),
                              schema='my_schema_name'
                              )

So it has a schema at the create_table level, but when running this script, the enum which gets created as a postgres TYPE in the database is still being created in the default (public) schema. When adding the schema name to the sa.Enum(...) as mentioned in my opening post in the expected behaviour part, it is being created in the right schema.

I hope that helped explaining a bit more in case it was still confusing.

renedupont avatar Sep 07 '21 10:09 renedupont

Is there any more news on this request? I am encountering the exact same issue

vinayman avatar Jun 28 '23 13:06 vinayman

no. please edit your files manually

zzzeek avatar Jun 28 '23 14:06 zzzeek