A database migration tool for SQLAlchemy.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Configuration classes and utilities for managing Alembic settings, database connections, and migration environments. The main configuration is handled through the Config class and associated utilities.
from alembic.config import Config, CommandLine
from alembic import commandMain configuration class for Alembic that manages settings from INI files and command-line options.
class Config:
def __init__(self, file_=None, toml_file=None, ini_section='alembic', output_buffer=None, stdout=sys.stdout, cmd_opts=None, config_args=None, attributes=None):
"""
Initialize Alembic configuration.
Args:
file_ (str): Path to configuration file (alembic.ini)
toml_file (str): Path to TOML configuration file (pyproject.toml) (v1.16.0+)
ini_section (str): INI section name to read from
output_buffer (StringIO): Buffer for output capture
stdout (file): Standard output stream
cmd_opts (Namespace): Command-line options from argparse
config_args (dict): Additional configuration arguments
attributes (dict): Custom attributes dictionary
"""
def get_main_option(self, name, default=None):
"""
Get a main configuration option.
Args:
name (str): Option name
default: Default value if option not found
Returns:
str|None: Option value
"""
def set_main_option(self, name, value):
"""
Set a main configuration option.
Args:
name (str): Option name
value (str): Option value
"""
def get_section(self, name, default=None):
"""
Get a configuration section as dictionary.
Args:
name (str): Section name
default (dict): Default dictionary if section not found
Returns:
dict: Section as key-value pairs
"""
def set_section_option(self, section, name, value):
"""
Set an option within a specific section.
Args:
section (str): Section name
name (str): Option name
value (str): Option value
"""
def remove_main_option(self, name):
"""
Remove a main configuration option.
Args:
name (str): Option name to remove
"""
def get_template_directory(self):
"""
Get the template directory path.
Returns:
str: Path to template directory
"""
def print_stdout(self, text, *arg):
"""
Print text to configured stdout.
Args:
text (str): Text to print
*arg: Additional arguments for string formatting
"""
def get_section_option(self, section, name, default=None):
"""
Get an option from a specific section.
Args:
section (str): Section name
name (str): Option name
default: Default value if not found
Returns:
Optional[str]: Option value
"""
def get_alembic_option(self, name, default=None):
"""
Get option from TOML alembic configuration (v1.16.0+).
Args:
name (str): Option name
default: Default value if not found
Returns:
Union[None, str, list[str], dict[str, str], list[dict[str, str]], int]: Option value
"""
def get_alembic_boolean_option(self, name):
"""
Get boolean option from TOML alembic configuration (v1.16.0+).
Args:
name (str): Option name
Returns:
bool: Boolean option value
"""
def get_version_locations_list(self):
"""
Get list of version locations from configuration.
Returns:
Optional[list[str]]: List of version location paths
"""
def get_prepend_sys_paths_list(self):
"""
Get list of paths to prepend to sys.path.
Returns:
Optional[list[str]]: List of paths to prepend
"""
def get_hooks_list(self):
"""
Get list of configured post-write hooks.
Returns:
list[PostWriteHookConfig]: List of hook configurations
"""Usage Examples:
# Create configuration from file
config = Config('alembic.ini')
# Create programmatic configuration
config = Config()
config.set_main_option('script_location', 'migrations')
config.set_main_option('sqlalchemy.url', 'postgresql://user:pass@localhost/db')
# Get database URL
db_url = config.get_main_option('sqlalchemy.url')
# Get section for engine configuration
db_config = config.get_section('sqlalchemy')Handle command-line parsing and execution.
class CommandLine:
def __init__(self, prog=None):
"""
Initialize command-line interface.
Args:
prog (str): Program name for help text
"""
def main(self, argv=None):
"""
Main entry point for command-line interface.
Args:
argv (list): Command-line arguments (sys.argv if None)
"""
def run_cmd(self, config, options):
"""
Execute a command with given configuration and options.
Args:
config (Config): Alembic configuration
options (Namespace): Parsed command-line options
"""Main entry point function for the alembic command.
def main(argv=None, prog=None, **kwargs):
"""
Console runner for Alembic.
Args:
argv (list): Command-line arguments
prog (str): Program name
**kwargs: Additional keyword arguments
"""Usage Example:
# Programmatic CLI execution
from alembic.config import main
main(['upgrade', 'head'])Standard alembic.ini configuration file structure:
# alembic.ini example
[alembic]
# Path to migration scripts
script_location = migrations
# Template used to generate migration files
file_template = %%(rev)s_%%(slug)s
# Timezone for revision timestamps
timezone = UTC
# Maximum length of revision slug
truncate_slug_length = 40
# SQLAlchemy logging levels
sqlalchemy.warn_20 = 1
# Database connection
sqlalchemy.url = postgresql://user:password@localhost/dbname
# 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:%SConfiguration for output and messaging formatting.
class MessagingOptions(TypedDict):
"""
Type definition for messaging configuration options.
"""
message_format: str
color: bool
# Example messaging configuration
messaging_opts = {
'message_format': '%(levelname)s: %(message)s',
'color': True
}Standard options in the [alembic] section:
script_location: Directory containing migration scriptsfile_template: Template for migration file namestimezone: Timezone for revision timestampstruncate_slug_length: Maximum length for revision slugssourceless: Whether to run migrations from .pyc filesversion_locations: Additional directories for version filesversion_path_separator: Separator for version pathsoutput_encoding: Encoding for output filesDatabase connection and SQLAlchemy configuration:
sqlalchemy.url: Database connection URLsqlalchemy.echo: Enable SQL loggingsqlalchemy.echo_pool: Enable connection pool loggingsqlalchemy.pool_pre_ping: Enable connection health checkssqlalchemy.pool_recycle: Connection recycling intervalVariables available in migration templates:
${revision}: Revision identifier${down_revision}: Previous revision identifier${branch_labels}: Branch labels${depends_on}: Dependencies${create_date}: Creation timestamp# From file
config = Config('alembic.ini')
# From specific section
config = Config('alembic.ini', ini_section='custom_section')
# Programmatic configuration
config = Config()
config.set_main_option('script_location', 'db/migrations')
config.set_main_option('sqlalchemy.url', database_url)
# With command-line options
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--sql', action='store_true')
args = parser.parse_args()
config = Config('alembic.ini', cmd_opts=args)def get_database_url():
# Dynamic URL resolution
import os
return os.environ.get('DATABASE_URL', 'sqlite:///alembic.db')
config = Config('alembic.ini')
config.set_main_option('sqlalchemy.url', get_database_url())
# Environment-specific configuration
env = os.environ.get('ENV', 'development')
config.set_main_option('script_location', f'migrations/{env}')# Multiple database sections
config = Config('alembic.ini')
# Primary database
primary_config = config.get_section('primary')
primary_url = primary_config['url']
# Secondary database
secondary_config = config.get_section('secondary')
secondary_url = secondary_config['url']
# Use with commands
command.upgrade(config, 'head', sql=False)from flask import Flask
from alembic.config import Config
from alembic import command
app = Flask(__name__)
def get_alembic_config():
config = Config()
config.set_main_option('script_location', 'migrations')
config.set_main_option('sqlalchemy.url', app.config['SQLALCHEMY_DATABASE_URI'])
return config
@app.cli.command()
def db_upgrade():
"""Run database migrations."""
config = get_alembic_config()
command.upgrade(config, 'head')
@app.cli.command()
def db_migrate():
"""Generate migration."""
config = get_alembic_config()
command.revision(config, autogenerate=True)from django.conf import settings
from alembic.config import Config
from alembic import command
def get_alembic_config():
config = Config()
config.set_main_option('script_location', 'alembic')
config.set_main_option('sqlalchemy.url', get_django_database_url())
return config
def get_django_database_url():
db = settings.DATABASES['default']
return f"{db['ENGINE']}://{db['USER']}:{db['PASSWORD']}@{db['HOST']}/{db['NAME']}"import tempfile
import os
def create_test_config():
"""Create configuration for testing."""
temp_dir = tempfile.mkdtemp()
config = Config()
config.set_main_option('script_location', os.path.join(temp_dir, 'migrations'))
config.set_main_option('sqlalchemy.url', 'sqlite:///:memory:')
return config, temp_dir
# Use in tests
config, temp_dir = create_test_config()
command.init(config, config.get_main_option('script_location'))Configuration errors may include:
CommandError: Invalid configuration or missing filesConfigParser exceptions: INI file parsing errorsAttributeError: Missing required configuration options# Configuration types
class Config:
config_file_name: Optional[str]
config_ini_section: str
cmd_opts: Optional[Namespace]
attributes: Dict[str, Any]
config_args: Dict[str, Any]
# Command function protocol
class CommandFunction(Protocol):
def __call__(self, config: Config, *args, **kwargs): ...
# Messaging configuration
class MessagingOptions(TypedDict, total=False):
message_format: str
color: boolInstall with Tessl CLI
npx tessl i tessl/pypi-alembic