Reputation: 649
I have a Flask (v0.10.1) application using Flask-SQLAlchemy (v2.0) and I'm trying to configure Pylint to check it. Running with Python 3.4.2.
First error was:
Instance of 'SQLAlchemy' has no 'Table' member (no-member)
And I fixed this one ignoring the check for member attributes on SQLAlchemy:
ignored-classes=SQLAlchemy
But I'm having a problem with the query member on entities:
Class 'UserToken' has no 'query' member (no-member)
Is there any way to fix this issue without having to ignore no-member errors on every query call?
Flask bootstrap:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app = Flask(__name__)
db.init_app(app)
app.run()
UserToken entity:
from app import db
class UserToken(db.Model):
user_token_id = db.Column(db.Integer, primary_key=True, index=True)
token_auth = db.Column(db.String(64), unique=True, nullable=False, index=True)
The controller:
from entities import UserToken
token = UserToken.query.filter(
UserToken.token_auth == token_hash,
).first()
Upvotes: 64
Views: 48369
Reputation: 43
Here is 2022.
My solution:
pip install pylint-flask-sqlalchemy
For VSCode (v2022.2.0), add below lines on .vscode/settings.json
:
"pylint.args": [
"--load-plugins",
"pylint_flask_sqlalchemy"
]
For terminal
pylint --load-plugins pylint_flask_sqlalchemy /path/{folder/file}
``
Upvotes: 2
Reputation: 1240
pip install pylint-flask
pip install pylint-flask-sqlalchemy
Load the installed plugin.
For example, if you use VS code, please edit settings.json file as follows:
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalchemy", "pylint_flask"]
If having other warnings, define remaining members in generated-members
in pylintrc
file.
Upvotes: 62
Reputation: 33770
--load-plugins pylint-flask
--load-plugins
needs the name of the python package to be imported. You can check this on command line (will get ImportError) if you do so. Pylinting in VS Code is nastier since you will not get any visible errors. Instead, you will have zero linting errors even if your code would have some linting problems.pylint-flask is a good plugin, but it is not even meant to tackle this problem! You can see the source code for yourself. There is no mentions about Flask-SQLAlchemy; it is only designed to fix issues (false positives) with Flask.
The pylint-flask-sqlalchemy was created to fix the pylint false positives with Flask-SQLAlchemy. After installing with
pip install pylint-flask-sqlalchemy
one should add it with1
# NOT: "pylint-flask-sqlalchemy"
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalchemy"]
1Applies directly only for VS Code. With other IDEs or command line, use the same arguments in the same order.
If used together, for some reason
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask", "pylint_flask_sqlalchemy"]
will not work but
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalchemy", "pylint_flask"]
does. So, presumably, the pylint-flask must be loaded after pylint-flask-sqlalchemy.
Upvotes: 12
Reputation: 11
The one that worked for me was switching to flake8 python linter. Below are the steps:
Open VSCode and run Ctrl+Shift+P (for Windows Users)
In the VSCode Search prompt, type Python:Select Linter
. You will see a list of all Linters and select flake8
.
If you do not have flake8
installed as a VScode extension for pylint, it will prompt you to install it. Proceed and install it.
Upvotes: 1
Reputation: 85
In the first solution in this page, following needs to be updated. Its a typo issue,
Instead of "pylint_flask"
in this settings.json parameter(in this line: "python.linting.pylintArgs": ["--load-plugins", "pylint_flask"])
it should be "python.linting.pylintArgs": ["--load-plugins", "pylint-flask"])
.
Upvotes: 5
Reputation: 281
Use pylint plugin pylint-flask-sqlalchemy
pip install pylint_flask_sqlalchemy
And in your settings.json of VisualCode
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalcheny"]
Upvotes: 8
Reputation: 99
The one that worked for me was switching to flake8
python linter. Below are the steps:
Ctrl+shift+P
(For Windows Users)Python:Select Linter
. You will see a list of all Linters and select flake8. Upvotes: 9
Reputation: 301
I meet the same issue when using flask_sqlalchemy. my solution is:
pylint --generate-rcfile>~/.config/pylintrc
and then find the
ignored-modules
line, rewrite it to:
ignored-modules=flask_sqlalchemy
all E1101 errors are gone.
Remeber to read the comment:
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis. It
# supports qualified module names, as well as Unix pattern matching.
Upvotes: 20
Reputation: 300
After trying a lot of these options, plugins and adding query and all. The only solution that erased those scoped_session errors was using:
pylint --generate-rcfile > pylintrc
pylint
on your module again.Upvotes: 7
Reputation: 61
Here's a version of joeforker's answer that dynamically adds all public methods from the Session
object back into a scoped_session
's locals at lint-time, instead of hardcoding a few well-known method names.
Define {path}/{to}/pylintplugins.py
:
import sys
from astroid import MANAGER, scoped_nodes
from astroid.builder import AstroidBuilder
from sqlalchemy.orm import Session
def register(_linter):
pass
def transform(cls):
if cls.name == 'scoped_session':
builder = AstroidBuilder(MANAGER)
module_node = builder.module_build(sys.modules[Session.__module__])
session_cls_node = [
c for c in module_node.get_children()
if getattr(c, "type", None) == "class" and c.name == Session.__name__
][0]
for prop in Session.public_methods:
cls.locals[prop] = [
c for c in session_cls_node.get_children()
if getattr(c, "type", None) == "method" and c.name == prop
]
MANAGER.register_transform(scoped_nodes.Class, transform)
And in your .pylintrc
file:
load-plugins={path}.{to}.pylintplugins
Upvotes: 6
Reputation: 1675
Another alternative is to add scoped_session
to the list of ignored classes:
# List of class names for which member attributes should not be checked (useful
# for classes with dynamically set attributes). This supports the use of
# qualified names.
ignored-classes=scoped_session
Upvotes: 2
Reputation: 41747
This is how I'm dealing with the issue for scoped_session
. Trivial to extend to check for more cls
names with SQLAlchemy attributes.
from astroid import MANAGER
from astroid import scoped_nodes
def register(_linter):
pass
def transform(cls):
if cls.name == 'scoped_session':
for prop in ['add', 'delete', 'query', 'commit', 'rollback']:
cls.locals[prop] = [scoped_nodes.Function(prop, None)]
MANAGER.register_transform(scoped_nodes.Class, transform)
Adapted from https://docs.pylint.org/en/1.6.0/plugins.html . Then make sure pylint loads your plugin.
pylint -E --load-plugins warning_plugin Lib/warnings.py
(or load it in pylintrc)
Upvotes: 0
Reputation: 843
Any class you declare as inheriting from db.Model
won't have query
member until the code runs so Pylint can't detect it.
The workaround for this besides ignoring no-member errors on every query
call is to add query
on the generated-members
list in a Pylint config file since it is a member that will only be created at runtime.
When you run Pylint, it will search for a configuration file as stated in its documentation:
You can specify a configuration file on the command line using the --rcfile option. Otherwise, Pylint searches for a configuration file in the following order and uses the first one it finds:
pylintrc
in the current working directory- If the current working directory is in a Python module, Pylint searches up the hierarchy of Python modules until it finds a pylintrc file. This allows you to specify coding standards on a module-by-module basis. Of course, a directory is judged to be a Python module if it contains an
__init__.py
file- The file named by environment variable
PYLINTRC
- if you have a home directory which isn’t
/root
:
.pylintrc
in your home directory.config/pylintrc
in your home directory/etc/pylintrc
So if you don't have a config and you want a system wide default config for pylint you can use pylint --generate-rcfile > /etc/pylintrc
. This will generate a commented configuration file according to the current configuration (or the default if you don't have one) that you can edit to your preferences.
p.s.: generated-members
on a config file is the right way to deal with this warning, as it's said by the commented config
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
Upvotes: 23
Reputation: 649
After a lot of investigation I was not able to make Pylint to understand this member, so I just added query
to the generated-members
list and the check is ignored.
It's not a perfect solution but it works.
Upvotes: 0