{"id":9328,"library":"sqlalchemy-diff","title":"SQLAlchemy Diff","description":"SQLAlchemy-diff is a Python library that provides a tool for comparing database schemas using SQLAlchemy. It helps identify differences between two database schemas, reporting on tables, columns, primary keys, foreign keys, indexes, unique constraints, check constraints, and enums. The current version is 1.1.1, and it maintains a release cadence of updates for compatibility and bug fixes, with major versions introducing breaking changes as seen with v1.0.0.","status":"active","version":"1.1.1","language":"en","source_language":"en","source_url":"https://github.com/gianchub/sqlalchemy-diff","tags":["sqlalchemy","database","schema","diff","comparison","migration","utility"],"install":[{"cmd":"pip install sqlalchemy-diff","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Core functionality relies on SQLAlchemy for database introspection and comparison. Requires SQLAlchemy >= 1.4.","package":"SQLAlchemy","optional":false}],"imports":[{"symbol":"create_engine","correct":"from sqlalchemy import create_engine"},{"note":"The `compare` function was available in pre-1.0.0 versions but was replaced by the `Comparer` class in v1.0.0 and later.","wrong":"from sqlalchemydiff import compare","symbol":"Comparer","correct":"from sqlalchemydiff.comparer import Comparer"}],"quickstart":{"code":"from sqlalchemy import create_engine, Column, Integer, String, MetaData, Table\nfrom sqlalchemydiff.comparer import Comparer\n\n# Define schema for database one (source)\nmetadata_one = MetaData()\nTable(\n    'users',\n    metadata_one,\n    Column('id', Integer, primary_key=True),\n    Column('name', String(50)),\n    Column('email', String(100), unique=True)\n)\n\n# Define schema for database two (target) with a difference\nmetadata_two = MetaData()\nTable(\n    'users',\n    metadata_two,\n    Column('id', Integer, primary_key=True),\n    Column('name', String(50)),\n    Column('address', String(200)) # Changed column\n)\n\n# Create in-memory SQLite engines for demonstration\nengine_one = create_engine('sqlite:///:memory:')\nengine_two = create_engine('sqlite:///:memory:')\n\n# Create tables in memory\nmetadata_one.create_all(engine_one)\nmetadata_two.create_all(engine_two)\n\n# Compare the schemas\ncomparer = Comparer(engine_one, engine_two)\nresult = comparer.compare(one_alias='Source DB', two_alias='Target DB')\n\nif result.is_match:\n    print('Schemas are identical!')\nelse:\n    print('Schemas differ! Differences:')\n    for error in result.errors:\n        print(f\"  - {error.description} (Table: {error.table_name}, Column: {error.column_name or 'N/A'}) [Severity: {error.severity}]\")\n\n# Example using from_params for automatic engine disposal\n# (Requires actual database URIs to connect)\n# try:\n#     comparer_from_params = Comparer.from_params(\n#         'sqlite:///:memory:',\n#         'sqlite:///:memory:',\n#         dispose_engines=True\n#     )\n#     result_from_params = comparer_from_params.compare()\n#     print('\\nComparison using from_params:')\n#     if result_from_params.is_match:\n#         print('Schemas are identical (from_params)!')\n#     else:\n#         print('Schemas differ (from_params)!')\n#         for error in result_from_params.errors:\n#             print(f\"  - {error.description}\")\n# except Exception as e:\n#     print(f\"Error with from_params example: {e}\")","lang":"python","description":"This quickstart demonstrates how to compare two SQLAlchemy database schemas using in-memory SQLite databases. It initializes two `MetaData` objects, creates corresponding tables in two separate engines, and then uses the `Comparer` class to identify differences. The output will detail discrepancies found, such as a changed column name. It also comments on `Comparer.from_params` for convenience with automatic engine disposal."},"warnings":[{"fix":"Review the official documentation and quickstart for v1.0.0+ to update imports and class usage from functions.","message":"Version 1.0.0 introduced a complete rewrite of the library, fundamentally changing the API. Code written for pre-1.0.0 versions will break and require significant refactoring.","severity":"breaking","affected_versions":"<1.0.0 to 1.0.0+"},{"fix":"Upgrade your Python environment to 3.10 or newer.","message":"As of version 1.0.4, `sqlalchemy-diff` requires Python 3.10 or higher. Running on older Python versions (e.g., 3.9) will result in installation or runtime errors.","severity":"breaking","affected_versions":"<1.0.4 on Python <3.10"},{"fix":"If needed, explicitly install `sqlalchemy-utils` in your project: `pip install sqlalchemy-utils`.","message":"The `sqlalchemy-utils` dependency was removed in v1.1.0. If your project indirectly relied on features from `sqlalchemy-utils` via `sqlalchemy-diff`, you might need to add `sqlalchemy-utils` as a direct dependency to your project.","severity":"deprecated","affected_versions":">=1.1.0"},{"fix":"Ensure `engine.dispose()` is called on manually created engines, or use `Comparer.from_params()` when possible.","message":"When manually creating `sqlalchemy.engine.Engine` instances and passing them to the `Comparer` constructor, you are responsible for managing their lifecycle, including calling `engine.dispose()` to close database connections. If using `Comparer.from_params()`, engine disposal is handled automatically if `dispose_engines=True` (which is the default behavior for `from_params`).","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Install the package using pip: `pip install sqlalchemy-diff`","cause":"The `sqlalchemy-diff` package is not installed in the current Python environment.","error":"ModuleNotFoundError: No module named 'sqlalchemydiff'"},{"fix":"Update your import statement to `from sqlalchemydiff.comparer import Comparer` and initialize the comparer as `comparer = Comparer(engine_one, engine_two)`.","cause":"Attempting to use the old `compare` function directly from the `sqlalchemydiff` module, which was removed in version 1.0.0. The API changed to use the `Comparer` class.","error":"AttributeError: module 'sqlalchemydiff' has no attribute 'compare'"},{"fix":"Verify the database connection URI (host, port, username, password, database name) is correct and ensure the database server is running and reachable.","cause":"The database connection URI is incorrect, credentials are invalid, or the target database server is not accessible or running.","error":"sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) fe_sendauth: no password supplied (or similar DB connection error)"},{"fix":"Ensure you provide both `engine_one` and `engine_two` when instantiating `Comparer`, for example: `comparer = Comparer(engine_one, engine_two)`.","cause":"The `Comparer` class requires two SQLAlchemy engine instances (representing the two schemas to compare) during its initialization.","error":"TypeError: Comparer() missing 1 required positional argument: 'engine_two'"}]}