Python Pylint 找不到 SQLAlchemy 查询成员

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28193025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 02:53:22  来源:igfitidea点击:

Pylint can't find SQLAlchemy query member

pythonpython-3.xsqlalchemyflask-sqlalchemypylint

提问by Pedro Teixeira

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.

我有一个使用 Flask-SQLAlchemy (v2.0) 的 Flask (v0.10.1) 应用程序,我正在尝试配置 Pylint 来检查它。使用 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:

我修复了这个忽略 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:

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)

The controller:

控制器:

from entities import UserToken

token = UserToken.query.filter(
    UserToken.token_auth == token_hash,
).first()

回答by Pedro Teixeira

After a lot of investigation I was not able to make Pylint to understand this member, so I just added queryto the generated-memberslist and the check is ignored.

经过大量调查,我无法让 Pylint 理解这个成员,所以我只是添加querygenerated-members列表中,并忽略了检查。

It's not a perfect solution but it works.

这不是一个完美的解决方案,但它有效。

回答by 0rkan

Any class you declare as inheriting from db.Modelwon't have querymember until the code runs so Pylint can't detect it.

在代码运行之前,您声明为继承自的任何类db.Model都不会拥有query成员,因此 Pylint 无法检测到它。

The workaround for this besides ignoring no-member errors on every querycall is to add queryon the generated-memberslist in a Pylint config file since it is a member that will only be created at runtime.

除了忽视对每一个无成员的错误造成这种情况的解决方法query调用是添加query了对generated-members在pylint的配置文件列表,因为它只会在运行时创建的成员。

When you run Pylint, it will search for a configuration file as stated in its documentation:

当您运行 Pylint 时,它将搜索其文档中所述的配置文件:

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:

  1. pylintrcin the current working directory
  2. 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__.pyfile
  3. The file named by environment variable PYLINTRC
  4. if you have a home directory which isn't /root:
    1. .pylintrcin your home directory
    2. .config/pylintrcin your home directory
  5. /etc/pylintrc

您可以使用 --rcfile 选项在命令行上指定配置文件。否则,Pylint 按以下顺序搜索配置文件并使用它找到的第一个:

  1. pylintrc在当前工作目录中
  2. 如果当前工作目录在 Python 模块中,Pylint 会向上搜索 Python 模块的层次结构,直到找到 pylintrc 文件。这允许您逐个模块地指定编码标准。当然,如果目录包含__init__.py文件,则判断为Python模块
  3. 由环境变量命名的文件 PYLINTRC
  4. 如果您的主目录不是/root
    1. .pylintrc在您的主目录中
    2. .config/pylintrc在您的主目录中
  5. /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.

因此,如果您没有配置并且想要 pylint 的系统范围默认配置,则可以使用pylint --generate-rcfile > /etc/pylintrc. 这将根据当前配置(如果没有,则为默认配置)生成一个带注释的配置文件,您可以根据自己的喜好对其进行编辑。

p.s.: generated-memberson a config file is the right way to deal with this warning, as it's said by the commented config

ps:generated-members在配置文件上是处理此警告的正确方法,正如注释的配置所说

  # 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.

回答by axis

I meet the same issue when using flask_sqlalchemy. my solution is:

我在使用flask_sqlalchemy 时遇到了同样的问题。我的解决方案是:

pylint --generate-rcfile>~/.config/pylintrc

and then find the

然后找到

ignored-modules

line, rewrite it to:

行,将其重写为:

ignored-modules=flask_sqlalchemy

all E1101 errors are gone.

所有 E1101 错误都消失了。

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.

回答by joeforker

This is how I'm dealing with the issue for scoped_session. Trivial to extend to check for more clsnames with SQLAlchemy attributes.

这就是我处理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)

Adapted from https://docs.pylint.org/en/1.6.0/plugins.html. Then make sure pylint loads your plugin.

改编自https://docs.pylint.org/en/1.6.0/plugins.html。然后确保 pylint 加载您的插件。

pylint -E --load-plugins warning_plugin Lib/warnings.py

pylint -E --load-plugins warning_plugin Lib/warnings.py

(or load it in pylintrc)

(或在 pylintrc 中加载它)

回答by jojonas

Another alternative is to add scoped_sessionto the list of ignored classes:

另一种选择是添加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

回答by Kurtiss Hare

Here's a version of joeforker's answer that dynamically adds all public methods from the Sessionobject back into a scoped_session's locals at lint-time, instead of hardcoding a few well-known method names.

这是 joeforker 答案的一个版本,它在 lint 时间将Session对象中的所有公共方法动态添加回 ascoped_session的本地,而不是硬编码一些众所周知的方法名称。

Define {path}/{to}/pylintplugins.py:

定义{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 .pylintrcfile:

在你的.pylintrc文件中:

load-plugins={path}.{to}.pylintplugins

回答by dondrzzy

After trying a lot of these options, plugins and adding query and all. The only solution that erased those scoped_session errors was using:

在尝试了很多这些选项、插件和添加查询之后。擦除这些 scoped_session 错误的唯一解决方案是使用:

  1. pylint --generate-rcfile > pylintrc
  2. look for the ignored_classes and add scoped_session after the comma, leave no space
  3. Run pylinton your module again.
  1. pylint --generate-rcfile > pylintrc
  2. 查找 ignore_classes 并在逗号后添加 scoped_session,不留空格
  3. pylint再次运行您的模块。

回答by Jun

Solution

解决方案

  1. pip install pylint-flask
  2. Load the installed plugin.

    For example, if you use VS code, please edit setting.json file as follows:

    "python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]

  1. pip install pylint-flask
  2. 加载已安装的插件。

    例如,如果您使用 VS 代码,请按如下方式编辑 setting.json 文件:

    "python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]

Optional

可选的

If having other warnings, define remaining members in generated-membersin pylintrcfile.

如果有其他警告,请generated-memberspylintrc文件中定义其余成员。

回答by Emz Amechu

The one that worked for me was switching to flake8python linter. Below are the steps:

对我flake8有用的是切换到python linter。以下是步骤:

  1. Open VSCode and run Ctrl+shift+P(For Windows Users)
  2. In the VSCode Search prompt, type Python:Select Linter. You will see a list of all Linters and select flake8.
  3. If you do not have flake8 installed as a VScode extension for pylint, it will prompt you to install it. Proceed and install it.
  1. 打开 VSCode 并运行Ctrl+shift+P(适用于 Windows 用户)
  2. 在 VSCode 搜索提示中,键入Python:Select Linter. 您将看到所有 Linter 的列表并选择 flake8。
  3. 如果你没有安装 flake8 作为 pylint 的 VScode 扩展,它会提示你安装它。继续并安装它。

回答by Saravana Kumar

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 shouldbe "python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]).

而不是"pylint_flask"在这个 settings.json 参数中(在这一行中: "python.linting.pylintArgs": ["--load-plugins", "pylint_flask"])应该"python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]).