Typing Stubs for SQLAlchemy
types-sqlalchemy is a PEP 561 type stub package designed to provide static type checking for the SQLAlchemy library. It enables type checkers such as MyPy, Pyright, Pytype, and PyCharm to analyze code that uses SQLAlchemy, improving code quality and catching potential errors at development time. This package is part of the `typeshed` project and primarily supports SQLAlchemy 1.x, with SQLAlchemy 2.0+ integrating native type annotations. It is actively maintained as part of typeshed.
Common errors
-
mypy: Duplicate module named 'sqlalchemy' (or similar errors with type conflicts)
cause This typically occurs when `types-sqlalchemy` is installed alongside SQLAlchemy 2.0+, which has its own native type annotations, leading to conflicting stub definitions.fixUninstall `types-sqlalchemy` via `pip uninstall types-sqlalchemy`. Ensure your SQLAlchemy version is 2.0 or newer and rely on its built-in typing. If you need 1.x stubs, ensure SQLAlchemy is also 1.x. -
Incompatible type for "name" of "User" (got "int", expected "Optional[str]")
cause This indicates a type mismatch in your code where a value of an incorrect type is being assigned to a SQLAlchemy column that has been type-hinted. For example, assigning an integer to a string column.fixAdjust the value being assigned to match the expected type hint (e.g., change `name=42` to `name='John Doe'`). Review your model definitions and assignments to ensure type consistency.
Warnings
- breaking SQLAlchemy versions 2.0 and newer include native type annotations. Using `types-sqlalchemy` alongside SQLAlchemy 2.0+ can lead to conflicts and incorrect type checking results. It is strongly recommended to uninstall `types-sqlalchemy` if you are using SQLAlchemy 2.0 or a newer version and rely on SQLAlchemy's built-in typing.
- gotcha There are alternative SQLAlchemy stub packages, notably `sqlalchemy-stubs`. While `types-sqlalchemy` is part of the official `typeshed` project and is plugin-agnostic, `sqlalchemy-stubs` provides a MyPy plugin for potentially more precise type inference in some complex cases. Choose one based on your specific type-checking needs and tooling.
- gotcha Contributions and fixes for `types-sqlalchemy` should be made directly to the `typeshed` repository on GitHub (`https://github.com/python/typeshed/tree/main/stubs/SQLAlchemy`), not to the `types-sqlalchemy` PyPI project directly.
Install
-
pip install types-sqlalchemy
Imports
- SQLAlchemy imports (e.g., Column, String, declarative_base)
from sqlalchemy import Column, Integer, String from sqlalchemy.orm import declarative_base, Mapped, mapped_column from typing import Optional
Quickstart
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import declarative_base, sessionmaker
from typing import Optional
# types-sqlalchemy provides stubs that enable type checkers
# to understand the types of SQLAlchemy objects like Column, String, etc.
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id: Mapped[int] = mapped_column(Integer, primary_key=True)
name: Mapped[str] = mapped_column(String)
email: Mapped[Optional[str]] = mapped_column(String, nullable=True)
def __repr__(self) -> str:
return f"<User(id={self.id}, name='{self.name}', email='{self.email}')>"
# Example usage (runtime, type-checked by types-sqlalchemy)
# In a real application, you would typically use an environment variable for the connection string
DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(DATABASE_URL)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
new_user = User(name='Alice', email='alice@example.com')
session.add(new_user)
session.commit()
retrieved_user: Optional[User] = session.query(User).filter_by(name='Alice').first()
if retrieved_user:
print(retrieved_user) # type: ignore
session.close()