@@ -6,14 +6,14 @@ Mypy plugin and stubs for SQLAlchemy
66[ ![ Build Status] ( https://travis-ci.org/dropbox/sqlalchemy-stubs.svg?branch=master )] ( https://travis-ci.org/dropbox/sqlalchemy-stubs )
77[ ![ Checked with mypy] ( http://www.mypy-lang.org/static/mypy_badge.svg )] ( http://mypy-lang.org/ )
88
9- This package contains [ type stubs] ( https://www.python.org/dev/peps/pep-0561/ ) and soon a
10- mypy plugin to provide more precise static types
11- and type inference for [ SQLAlchemy framework ] ( http://docs.sqlalchemy.org/en/latest/ ) .
12- SQLAlchemy uses some Python "magic" that
13- makes having precise types for some code patterns problematic. This is why we need to
14- accompany the stubs with mypy plugins. The final goal is to be able to get precise types
15- for most common patterns. A simple example:
16-
9+ This package contains [ type stubs] ( https://www.python.org/dev/peps/pep-0561/ ) and a
10+ [ mypy plugin] ( https://mypy.readthedocs.io/en/latest/extending_mypy.html#extending-mypy-using-plugins )
11+ to provide more precise static types and type inference for
12+ [ SQLAlchemy framework ] ( http://docs.sqlalchemy.org/en/latest/ ) . SQLAlchemy uses some
13+ Python "magic" that makes having precise types for some code patterns problematic.
14+ This is why we need to accompany the stubs with mypy plugins. The final goal is to
15+ be able to get precise types for most common patterns. Currently, basic operations
16+ with models are supported. A simple example:
1717``` python
1818from sqlalchemy.ext.declarative import declarative_base
1919from sqlalchemy import Column, Integer, String
@@ -25,11 +25,33 @@ class User(Base):
2525 id = Column(Integer, primary_key = True )
2626 name = Column(String)
2727
28- user: User
28+ user = User(id = 42 , name = 42 ) # Error: Incompatible type for "name" of "User"
29+ # (got "int", expected "Optional[str]"
2930user.id # Inferred type is "int"
30- User.name # Inferred type is "Column[str]"
31+ User.name # Inferred type is "Column[Optional[str]]"
32+ ```
33+
34+ Some auto-generated attributes are added to models. Simple relationships
35+ are supported but require models to be imported:
36+ ``` python
37+ from typing import TYPE_CHECKING
38+ if TYPE_CHECKING :
39+ from models.address import Address
40+
41+ ...
42+
43+ class User (Base ):
44+ __tablename__ = ' users'
45+ id = Column(Integer, primary_key = True )
46+ name = Column(String)
47+ address = relationship(' Address' ) # OK, mypy understands string references.
3148```
3249
50+ The next step is to support precise types for table definitions (e.g.
51+ inferring ` Column[Optional[str]] ` for ` users.c.name ` , currently it is just
52+ ` Column[Any] ` ), and precise types for results of queries made using ` query() `
53+ and ` select() ` .
54+
3355## Installation
3456
3557To install the latest version of the package:
@@ -45,6 +67,12 @@ stable version as:
4567pip install -U sqlalchemy-stubs
4668```
4769
70+ * Important* : you need to enable the plugin in your mypy config file:
71+ ```
72+ [mypy]
73+ plugins = sqlmypy
74+ ```
75+
4876## Development Setup
4977
5078First, clone the repo and cd into it, like in _ Installation_ , then:
0 commit comments