30

I'm trying to add type hints to my SQLAlchemy script:

connection_string: str = "sqlite:///:memory:"
engine = create_engine(connection_string)
session = Session(bind=engine)
reveal_type(engine)
reveal_type(session)

I've ran this script against mypy but both types comes back as Any. What type should the engine and session variable be?

Johnny Metz
  • 5,977
  • 18
  • 82
  • 146
  • Are you using https://github.com/dropbox/sqlalchemy-stubs or something similar, btw? Mypy doesn't bake in type hints for sqlalchemy. – Michael0x2a May 13 '19 at 20:13

2 Answers2

43

Figured it out:

connection_string: str = "sqlite:///:memory:"
engine = create_engine(connection_string)
session = Session(bind=engine)
print(type(engine))   # sqlalchemy.engine.base.Engine
print(type(session))  # sqlalchemy.orm.session.Session

Thus, type hinting is achieved the following way for example:

from sqlalchemy.engine.base import Engine

def test_func(engine: Engine):
    pass
blackraven
  • 5,284
  • 7
  • 19
  • 45
Johnny Metz
  • 5,977
  • 18
  • 82
  • 146
3

If you're like me who found this question while trying to figure out how to annotate SQLAlchemy stuff then follow this guide. Firstly, these are correct annotations:

from sqlalchemy import create_engine

from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session

connection_string: str = "sqlite:///:memory:"
engine: Engine = create_engine(connection_string)
session: Session = Session(bind=engine)

So easy? Oh, no! This is what mypy says now:

main.py:1: error: Cannot find implementation or library stub for module named "sqlalchemy"
main.py:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
main.py:2: error: Cannot find implementation or library stub for module named "sqlalchemy.engine"
main.py:3: error: Cannot find implementation or library stub for module named "sqlalchemy.orm"
Found 3 errors in 1 file (checked 1 source file)

That's because SQLAlchemy is not statically typed, so to make it work you need to install stub files (files with extension .pyi). Fortunately, there are solutions. If you're using SQLAlchemy 1.4+ you can use official stubs, in other cases use sqlalchemy-stubs typing annotations published by Dropbox.

Install it via pip (or use any other package manager):

pip install 'sqlalchemy[mypy]'

To get started, all you need to do is create a mypy.ini file with the following contents:

[mypy]
plugins = sqlalchemy.ext.mypy.plugin

Then run it via mypy main.py and see no issues!


Take into account that this mypy plugin was developed especially for SQLAlchemy 1.4-2.x versions. According to the docs:

SQLAlchemy version 2.0, when released, will include new constructs that will allow for construction of declarative mappings in place which will support proper typing directly, without the need for plugins.

funnydman
  • 9,083
  • 4
  • 40
  • 55