Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render table .info in create table, also fix typing for rewriter #1329

Closed
zzzeek opened this issue Oct 19, 2023 Discussed in #1328 · 1 comment
Closed

render table .info in create table, also fix typing for rewriter #1329

zzzeek opened this issue Oct 19, 2023 Discussed in #1328 · 1 comment
Labels
autogenerate - rendering bug Something isn't working

Comments

@zzzeek
Copy link
Member

zzzeek commented Oct 19, 2023

Discussed in #1328

Originally posted by BayerSe October 19, 2023
Hi,

our Oracle db requires partitions for some of the tables, which we used to add using alembic with the following steps. These are based on the proposal of @zzzeek here (for nicer formatting see here).

It's been a long time since I needed a change in the schema, so I only now realized that there seems to have been a regression / change in behavior.

Main code:

from sqlalchemy import MetaData, Column, String
from sqlalchemy.ext.declarative import declarative_base

metadata = MetaData()
Base = declarative_base(metadata=metadata)


class Table(Base):
    __tablename__ = 'Table'
    name = Column(String(10), primary_key=True)
    __table_args__ = {'info': {'oracle_partition': "PARTITION BY ..."}}

This rewriter is added as process_revision_directives of context.configure in env.py with the goal of adding the info dict to the create_table statement:

writer = rewriter.Rewriter()

@writer.rewrites(ops.CreateTableOp)
def add_info_to_table(context, revision, op):
    op.kw["info"] = op.columns[0].table.info
    return ops.CreateTableOp(
            table_name=op.table_name,
            columns=op.columns,
            schema=op.schema,
            _namespace_metadata=op._namespace_metadata,
            _constraints_included=op._constraints_included,
            **op.kw,
        )

We add this to the migration scripts, which adds the partition command to the created statement:

import sqlalchemy as sa
from alembic import op
import textwrap

@sa.ext.compiler.compiles(sa.schema.CreateTable, "oracle")
def _add_suffixes(element, compiler, **kw):  # type: ignore
    text = compiler.visit_create_table(element, **kw)
    if "oracle_partition" in element.element.info:
        text += textwrap.dedent(element.element.info["oracle_partition"]).strip()
    return text

For alembic==1.6.5 and sqlalchemy==1.3.24 this result in the following auto-generated update command:

op.create_table(
    "Table",
    sa.Column("name", sa.String(length=10), nullable=False),
    sa.PrimaryKeyConstraint("name"),
    info={"oracle_partition": "PARTITION BY ..."},
)

However, for alembic==1.12.0 and sqlalchemy==2.0.22, the info is not added anymore, i.e. I just get

op.create_table(
    "Table",
    sa.Column("name", sa.String(length=10), nullable=False),
    sa.PrimaryKeyConstraint("name"),
)

I checked version alembic==1.7.0 as well, it broke between 1.6.5 and 1.7.0. In the changelog I found this comment, could that be related?

Thanks and regards
Sebastian

@zzzeek zzzeek added bug Something isn't working autogenerate - rendering labels Oct 19, 2023
@sqla-tester
Copy link
Collaborator

Mike Bayer has proposed a fix for this issue in the main branch:

render .info in create_table https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/4930

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autogenerate - rendering bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants