Pylint找不到SQLAlchemy查询成员

时间:2015-01-28 13:04:15

标签: python python-3.x sqlalchemy flask-sqlalchemy pylint

我有一个使用Flask-SQLAlchemy(v2.0)的Flask(v0.10.1)应用程序,我试图配置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)

有没有办法解决这个问题,而不必在每次查询调用时忽略无成员错误?


Flask bootstrap:

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

13 个答案:

答案 0 :(得分:26)

解决方案

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

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

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

可选

如果还有其他警告,请在generated-members文件的pylintrc中定义其余成员

答案 1 :(得分:17)

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

除了忽略每个query调用上的无成员错误之外,解决方法是在Pylint配置文件中的query列表中添加generated-members,因为它只是一个成员在运行时创建。

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

  

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

     
      当前工作目录中的
  1. pylintrc
  2.   
  3. 如果当前工作目录位于Python模块中,Pylint会搜索Python模块的层次结构,直到找到pylintrc文件。这允许您逐个模块地指定编码标准。当然,如果目录包含__init__.py文件
  4. ,则该目录被判定为Python模块   
  5. 由环境变量PYLINTRC
  6. 命名的文件   
  7. 如果您的主目录不是/root:      
        
    1. .pylintrc在您的主目录中
    2.   
    3. .config/pylintrc在您的主目录中
    4.   
  8.   
  9. /etc/pylintrc
  10.   

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

配置文件中的

p.s。: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.

答案 2 :(得分:13)

使用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.

答案 3 :(得分:8)

在此页面的第一个解决方案中,需要更新以下内容。这是拼写错误,

而不是此settings.json参数中的"pylint_flask"(在此行:"python.linting.pylintArgs": ["--load-plugins", "pylint_flask"])中,它应为 "python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]) 。< / p>

答案 4 :(得分:6)

这是一个joeforker的答案版本,它在lint-time动态地将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 :(得分:6)

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

  1. pylint --generate-rcfile > pylintrc
  2. 查找ignored_classes并在逗号后添加scoped_session,不留空格
  3. 再次在您的模块上运行pylint

答案 6 :(得分:5)

警告:不要只是--load-plugins pylint-flask

  • 通过执行此操作(使用破折号而不是下划线),您将完全禁用pylint !这是因为--load-plugins需要python软件包的名称。如果这样做,您可以在命令行上检查(将得到ImportError)。由于您不会收到任何可见的错误,因此VS Code中的拼写是比较麻烦的。取而代之的是,即使您的代码有一些掉毛问题,您也将没有掉毛错误。

pylint烧瓶不起作用

pylint-flask是一个很好的插件,但是它甚至还不能解决这个问题!您可以自己see the source code。没有提到Flask-SQLAlchemy。它仅用于解决Flask的问题(误报)。

pylint-flask-sqlalchemy

pylint-flask-sqlalchemy was created使用Flask-SQLAlchemy修复pylint误报。用

安装后
pip install pylint-flask-sqlalchemy

应该添加 1

# NOT: "pylint-flask-sqlalchemy"
"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalchemy"]

1 仅直接用于 VS Code 。在其他IDE或命令行中,以相同的顺序使用相同的参数。

带有pyintint-flask-sqlalchemy的烧瓶-

如果出于某种原因一起使用

"python.linting.pylintArgs": ["--load-plugins", "pylint_flask", "pylint_flask_sqlalchemy"]

不起作用,但

"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalchemy", "pylint_flask"]

确实。因此,大概必须在 pylint-flask-sqlalchemy之后加载pylint-flask。

答案 7 :(得分:2)

最适合我的是切换到flake8 python linter。步骤如下:

  1. 打开VSCode并运行Ctrl+shift+P(对于Windows用户)
  2. 在VSCode搜索提示中,键入Python:Select Linter。您将看到所有Linters的列表,然后选择flake8。
  3. 如果尚未将flake8安装为pylint的VScode扩展,它将提示您安装它。继续并安装它。

答案 8 :(得分:1)

另一种方法是将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

答案 9 :(得分:1)

使用pylint插件pylint-flask-sqlalchemy

pip install pylint_flask_sqlalchemy

并在您的VisualCode的settings.json中

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

答案 10 :(得分:1)

最适合我的是切换到flake8 python linter。步骤如下:

  1. 打开VSCode并运行 Ctrl + Shift + P (对于Windows用户)

  2. 在VSCode搜索提示中,键入Python:Select Linter。您将看到所有Linter的列表,然后选择flake8

  3. 如果尚未安装flake8作为pylint的VScode扩展,它将提示您安装它。继续并安装它。

答案 11 :(得分:0)

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

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

答案 12 :(得分:0)

这就是我处理scoped_session问题的方法。使用SQLAlchemy属性扩展以检查更多cls名称的过程非常简单。

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中加载​​)