Pylint не может найти элемент запроса SQLAlchemy
У меня есть приложение Flask (v0.10.1), использующее Flask-SQLAlchemy (v2.0), и я пытаюсь настроить Pylint, чтобы проверить его. Работа с Python 3.4.2.
Первая ошибка:
Instance of 'SQLAlchemy' has no 'Table' member (no-member)
И я исправил это, игнорируя проверку атрибутов члена SQLAlchemy:
ignored-classes=SQLAlchemy
Но у меня проблема с членом запроса на сущности:
Class 'UserToken' has no 'query' member (no-member)
Есть ли способ исправить эту проблему без необходимости игнорировать ошибки без участия каждого запроса?
Загрузочный лоток:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
app = Flask(__name__)
db.init_app(app)
app.run()
Объект UserToken:
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)
Контроллер:
from entities import UserToken
token = UserToken.query.filter(
UserToken.token_auth == token_hash,
).first()
Ответы
Ответ 1
Решение
-
pip install pylint-flask
-
Загрузите установленный плагин.
Например, если вы используете код VS, отредактируйте файл setting.json следующим образом: (открывается с помощью команды "Файл"> "Настройки"> "Настройки" search, найдите файл settings.json, и один из параметров позволит вам его отредактировать)
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask"]
Необязательный
Если есть другие предупреждения, определите оставшиеся члены в generated-members
в файле pylintrc
Ответ 2
Любой класс, который вы объявляете как наследующий от db.Model
, не будет иметь член query
до тех пор, пока код не будет запущен, поэтому Pylint не сможет его обнаружить.
Обходной путь для этого, кроме игнорирования ошибок без члена в каждом вызове query
, заключается в добавлении query
в список generated-members
в файле конфигурации Pylint, поскольку он является членом, который будет создан только во время выполнения.
Когда вы запустите Pylint, он будет искать конфигурационный файл, как указано в документации:
Вы можете указать файл конфигурации в командной строке, используя параметр -rcfile. В противном случае Pylint ищет файл конфигурации в следующем порядке и использует первый найденный:
-
pylintrc
в текущем рабочем каталоге - Если текущий рабочий каталог находится в модуле Python, Pylint ищет иерархию модулей Python, пока не найдет файл pylintrc. Это позволяет указывать стандарты кодирования по модулю. Конечно, каталог считается модулем Python, если он содержит файл
__init__.py
- Файл с именем переменной окружения
pylintrc
- если у вас есть домашний каталог, который не является
/root
: -
.pylintrc
в вашем домашнем каталоге -
.config/pylintrc
в вашем домашнем каталоге
-
/etc/pylintrc
Итак, если у вас нет конфигурации, и вы хотите иметь системную конфигурацию по умолчанию для pylint, вы можете использовать pylint --generate-rcfile > /etc/pylintrc
. Это приведет к созданию файла конфигурации с комментариями в соответствии с текущей конфигурацией (или по умолчанию, если у вас ее нет), которую вы можете изменить в своих настройках.
p.s.: generated-members
в файле конфигурации - это правильный способ справиться с этим предупреждением, как сказано в комментариях 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.
Ответ 3
Я сталкиваюсь с той же проблемой при использовании flask_sqlalchemy. мое решение:
pylint --generate-rcfile>~/.config/pylintrc
а затем найти
ignored-modules
строка, перепишите его так:
ignored-modules=flask_sqlalchemy
все ошибки E1101 исчезли.
Помните, чтобы прочитать комментарий:
# 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.
Ответ 4
Здесь приведена версия joeforker, которая динамически добавляет все общедоступные методы из объекта Session
обратно в локаторы scoped_session
во временное время, вместо жесткого кодирования нескольких известных имен методов.
Определить {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)
И в вашем файле .pylintrc
:
load-plugins={path}.{to}.pylintplugins
Ответ 5
Перепробовав множество этих опций, плагины и добавив запрос и все. Единственное решение, которое стерло эти ошибки scoped_session, использовало:
-
pylint --generate-rcfile > pylintrc
- найдите ignored_classes и добавьте scoped_session после запятой, не оставляйте пробела
- Запустите
pylint
на вашем модуле снова.
Ответ 6
Тот, который работал для меня, переключался на flake8
python flake8
. Ниже приведены шаги:
- Откройте VSCode и запустите
Ctrl+shift+P
(для пользователей Windows) - В строке поиска VSCode введите
Python:Select Linter
. Вы увидите список всех линтеров и выберите flake8. - Если у вас не установлено flake8 в качестве расширения VScode для pylint, вам будет предложено установить его. Продолжить и установить его.
Ответ 7
Другой альтернативой является добавить scoped_session
в список игнорируемых классов:
# 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
Ответ 8
После большого расследования я не смог заставить Pylint понять этот член, поэтому я просто добавил query
в список generated-members
, и проверка игнорируется.
Это не идеальное решение, но оно работает.
Ответ 9
Вот как я занимаюсь проблемой для scoped_session
. Тривиальное расширение для проверки более cls
имен с атрибутами SQLAlchemy.
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)
Адаптировано из https://docs.pylint.org/en/1.6.0/plugins.html. Затем убедитесь, что pylint загружает ваш плагин.
pylint -E --load-plugins warning_plugin Lib/warnings.py
(или загрузить его в pylintrc)