Alembic detects existing changes if db username equals postgres schema name
alexvas96 opened this issue · comments
Describe the bug
Alembic detects existing changes if db username equals postgres schema name.
Problem occurs only if parameter include_name
is passed in env.py
.
Expected behavior
Alembic generates empty migration.
To Reproduce
Project structure
.
├── alembic.ini
└── src
├── migrations
│ ├── env.py
│ ├── script.py.mako
│ └── versions
│ └── 20240318_2128_722179d9516c_initial.py
└── models.py
File: src/models.py
from sqlalchemy import MetaData, Column, BigInteger, String, Identity
from sqlalchemy.orm import DeclarativeBase
metadata = MetaData(schema='example')
class Base(DeclarativeBase):
metadata = metadata
class Customer(Base):
__tablename__ = 'customers'
id = Column(BigInteger, Identity(always=True), primary_key=True)
name = Column(String)
email = Column(String)
File: src/migrations/env.py
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
from models import Base
config = context.config
if config.config_file_name is not None:
fileConfig(config.config_file_name)
target_metadata = Base.metadata
def include_name(name, type_, parent_names):
if type_ == 'schema':
return name == target_metadata.schema
return True
def run_migrations_offline() -> None:
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
include_name=include_name,
include_schemas=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
include_name=include_name,
include_schemas=True,
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
File: src/migrations/versions/20240318_2128_722179d9516c_initial.py
"""initial
Revision ID: 722179d9516c
Revises:
Create Date: 2024-03-18 21:28:38.818940
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = '722179d9516c'
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.execute('CREATE SCHEMA example')
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('customers',
sa.Column('id', sa.BigInteger(), sa.Identity(always=True), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('id'),
schema='example'
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('customers', schema='example')
# ### end Alembic commands ###
op.execute('DROP SCHEMA example')
alembic.ini
[alembic]
script_location = src/migrations
file_template = %%(year)d%%(month).2d%%(day).2d_%%(hour).2d%%(minute).2d_%%(rev)s_%%(slug)s
prepend_sys_path = .
version_path_separator = os
sqlalchemy.url = postgresql://example:pass@localhost:5432/db
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
sqlalchemy.url in alembic.ini: postgresql://example:pass@localhost:5432/db
alembic upgrade head
alembic revision --autogenerate -m "test"
Output:
INFO [alembic.autogenerate.compare] Detected added table 'customers'
Autogenerated migration:
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('customers',
sa.Column('id', sa.BigInteger(), sa.Identity(always=True), nullable=False),
sa.Column('name', sa.String(), nullable=True),
sa.Column('email', sa.String(), nullable=True),
sa.PrimaryKeyConstraint('id'),
schema='example'
)
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('customers', schema='example')
# ### end Alembic commands ###
If I change the username in DSN (postgresql://user:pass@localhost:5432/db) to something that is not equal to the schema name, I get an empty migration.
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
Error
No errors.
Versions.
- OS: Ubuntu 22.04.4 LTS
- Python: Python 3.11.6
- Alembic: alembic 1.13.1
- SQLAlchemy: 2.0.28
- Database: PostgreSQL
- DBAPI: psycopg2-binary==2.9.9
Have a nice day!