Подтвердить что ты не робот

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()
4b9b3361

Ответ 1

Решение

  1. pip install pylint-flask
  2. Загрузите установленный плагин.

    Например, если вы используете код 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, использовало:

  1. pylint --generate-rcfile > pylintrc
  2. найдите ignored_classes и добавьте scoped_session после запятой, не оставляйте пробела
  3. Запустите pylint на вашем модуле снова.

Ответ 6

Тот, который работал для меня, переключался на flake8 python flake8. Ниже приведены шаги:

  1. Откройте VSCode и запустите Ctrl+shift+P (для пользователей Windows)
  2. В строке поиска VSCode введите Python:Select Linter. Вы увидите список всех линтеров и выберите flake8.
  3. Если у вас не установлено 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)