sqlalchemy-stubs icon indicating copy to clipboard operation
sqlalchemy-stubs copied to clipboard

Stubs for Flask-SQLAlchemy

Open r-darwish opened this issue 5 years ago • 18 comments

Thank you for this project. Is it possible to provides stubs for Flask-SQLAlchemy as well?

r-darwish avatar Mar 06 '19 12:03 r-darwish

Theoretically, there are no obstacles in generating some basic stubs and writing a mypy plugin for Flask-SQLAlchemy. But this is a large piece of work, and it is unlikely I will work on this soon. However, if there are volunteers to help with this, I can explain what to do and give some advices.

ilevkivskyi avatar Mar 08 '19 02:03 ilevkivskyi

I can try if you can give me some guidance

r-darwish avatar Mar 10 '19 18:03 r-darwish

The first step would be to generate stubs. This is the process:

  • Install the latest mypy version
  • Clone the Flask-SQLAlchemy repo
  • Run stubgen flask_sqlalchemy, output the result to flask_sqlalchemy-stubs
  • Manually add some types following the docs
  • Try type-checking some code using these stubs (you might need to update setup.py accordingly)
  • Write a mypy plugin for flask_sqlalchemy. You can look at what @bryanforbes is doing for Gino, it looks very similar.
  • Note this might need some fixes to mypy plugin hooks (I can also help with this if it will be necessary).

The ultimate question is where do we put all this, should this be a separate package or we can merge this here? @bryanforbes what is your opinion?

ilevkivskyi avatar Mar 11 '19 22:03 ilevkivskyi

You can use these stubs with flask_sqlalchemy right now with just a small amount of legwork. This article sums it up excellently but the basic gist is that you define your own custom base model separate from the flask implementation and use sqlalchemys declarative_base. That way when you define models you import that as your base instead of flask's db:

from .models.base import Model

and when you initialize the flask app, you import that same Model to tie it to flasks session and session management. It was really quite a simple process to setup and I'm now consuming these stubs in my flask app!

I'm sure this doesn't cover anything and there will be a few gotchas, but at the very least this allows all your SQLAlchemy models to by typed.

rmilejcz avatar Apr 04 '19 19:04 rmilejcz

@rmilejcz Could you please give some more details? Are you using if typing.TYPE_CHECKING: ...? Can you show some code that uses Flask-SQLAlchemy and has a type error caught by mypy using these stubs?

ilevkivskyi avatar Apr 09 '19 15:04 ilevkivskyi

Would be nice!

revmischa avatar Jun 18 '19 11:06 revmischa

@rmilejcz Can you give a little example please? I randomly already had my flask_sqlalchemy Models setup like that doc, but it doesn't seem to work fully.

My attr instance types read Union[Column[_T], T], instead of just T.

j-walker23 avatar Jul 27 '19 06:07 j-walker23

Hi folks: Can I PR?

tapaswenipathak avatar Sep 08 '19 08:09 tapaswenipathak

@tapaswenipathak Sure, but be aware this is not a small issue.

ilevkivskyi avatar Sep 09 '19 09:09 ilevkivskyi

@tapaswenipathak I will love you forever

j-walker23 avatar Sep 14 '19 23:09 j-walker23

Any update on this? Any recommended work-around?

At the moment, I get:

error: Name 'db.Model' is not defined

They are of type sqlalchemy.ext.declarative.api.Model, but I'm not even sure why it says that it is not defined.

MartinThoma avatar Jan 24 '20 16:01 MartinThoma

They are of type sqlalchemy.ext.declarative.api.Model, but I'm not even sure why it says that it is not defined.

there is no such type. in fact, sqlalchemy does not even use the term model at all.

wbolster-eiq avatar Feb 06 '20 19:02 wbolster-eiq

For any one looking for a workaround, this is what I went with for now.

from app import db
from sqlalchemy.ext.declarative import DeclarativeMeta

BaseModel: DeclarativeMeta = db.Model


class MyModel(BaseModel): ...

If you are using flask_sqlalchemy then you can use from flask_sqlalchemy.model import DefaultMeta instead of DeclarativeMeta.

holdenrehg avatar Mar 06 '20 16:03 holdenrehg

I tried @holdenrehg 's workaround for flask_sqlalchemy but then got this error:

error: Class cannot subclass 'BaseModel' (has type 'Any')

traviscook21 avatar Mar 09 '20 21:03 traviscook21

Hello, I have just created one, could anyone have a try? It's just for testing now.

https://github.com/ssfdust/flask-sqlalchemy-stubs

ssfdust avatar Aug 04 '20 03:08 ssfdust

Hello, I have just created one, could anyone have a try? It's just for testing now.

https://github.com/ssfdust/flask-sqlalchemy-stubs

I am getting a db.Model is not defined even after setting up flask-sqlalchemy-stubs. It me be that I haven't configured it correctly though, because we are using custom classes for models/queries.

bzhr avatar Jan 14 '21 13:01 bzhr

Hello, I have just created one, could anyone have a try? It's just for testing now. https://github.com/ssfdust/flask-sqlalchemy-stubs

I am getting a db.Model is not defined even after setting up flask-sqlalchemy-stubs. It me be that I haven't configured it correctly though, because we are using custom classes for models/queries.

I have updated the repo recently, do you upgrade to the latest version? On the other hand, if you are using pycharm, could you provide more detail information, for example, which plugin reports the error or the source code.

ssfdust avatar Jan 15 '21 05:01 ssfdust

Hello, I have just created one, could anyone have a try? It's just for testing now. https://github.com/ssfdust/flask-sqlalchemy-stubs

I am getting a db.Model is not defined even after setting up flask-sqlalchemy-stubs. It me be that I haven't configured it correctly though, because we are using custom classes for models/queries.

I have updated the repo recently, do you upgrade to the latest version? On the other hand, if you are using pycharm, could you provide more detail information, for example, which plugin reports the error or the source code.

Thanks for the reply. We got it working actually. The thing is, we have typed our implementations of Models and Queries ourselves, so there were conflicts between our implementation and this library. But after a little bit work the typing works on Models, Columns and Queries.

One thing that was a causing some issues is that the declared_attr's first argument is typed as self, but this is a class method and it should be cls. I was thinking that maybe I should open a separate issue for this. https://github.com/dropbox/sqlalchemy-stubs/blob/55470ceab8149db983411d5c094c9fe16343c58b/sqlalchemy-stubs/ext/declarative/api.pyi#L16

bzhr avatar Jan 15 '21 08:01 bzhr