【问题标题】:Pylint can't find SQLAlchemy query memberPylint 找不到 SQLAlchemy 查询成员
【发布时间】:2015-03-27 09:33:55
【问题描述】:

我有一个使用 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)

有什么方法可以解决这个问题,而不必在每次查询调用时都忽略 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()

【问题讨论】:

  • Flake8 是一个选项,但现在我将 query 添加到 Pylint 的 generated-members

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


【解决方案1】:

解决方案

pip install pylint-flask

pip install pylint-flask-sqlalchemy

加载已安装的插件。

例如,如果你使用 VS 代码,请编辑 settings.json 文件如下:

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

可选

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

【讨论】:

  • 在这样做之后,我仍然会遇到同样的错误,例如Instance of 'SQLAlchemy' has no 'Column' member (no-member)
  • 这似乎对我不起作用..也许还有其他需要设置的设置
  • 这不/不应该工作,。看插件源码,跟sqlalchemy没关系。只有ignored-modulesgenerated-members 帮助。
  • 对我来说以下作品:"python.linting.pylintArgs": ["--load-plugins", "pylint-flask"]
  • 我必须使用"python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalchemy"](注意下划线),否则pylint会抛出ImportError: No module named 'pylint-flask-sqlalchemy',而且它不能只添加pylint-flask,我需要插件pylint-flask-sqlalchemy建议stackoverflow.com/a/58979882/4112816
【解决方案2】:

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

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

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

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

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

因此,如果您没有配置并且想要 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.

【讨论】:

  • 您的意思是添加所有使用的 sql_alchemy 成员是处理这个问题的正确方法吗?这既乏味又可能掩盖对不同类的相似成员名称的进一步警告。在我看来,这不是最好的方式。
【解决方案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】:

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

  • 通过这样做(使用破折号而不是下划线)您将完全禁用pylint!这是因为--load-plugins 需要要导入的python 包的名称。如果你这样做,你可以在命令行上检查这个(会得到 ImportError)。 VS Code 中的 Pylinting 更糟糕,因为您不会看到任何可见的错误。相反,即使您的代码存在一些 linting 问题,您的 linting 错误也将为零。

pylint-flask 不起作用

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

pylint-flask-sqlalchemy

​​>

pylint-flask-sqlalchemywas 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 或命令行,以相同的顺序使用相同的参数。

pylint-flask 与 pylint-flask-sqlalchemy

​​>

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

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

行不通但是

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

确实如此。因此,据推测,pylint-flask 必须在 pylint-flask-sqlalchemy 之后加载。

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 它也对我有用。没有适用于 pylint 的解决方案
    • 剧透警告:我意外地得到了很多新的红色波浪线,因为 flake8 linting 与 pylint linting 不同。真是出乎意料
    • 我喜欢这个。不想花时间配置 linter :-)
    【解决方案6】:

    使用 pylint 插件 pylint-flask-sqlalchemy

    pip install pylint_flask_sqlalchemy
    

    在你的 VisualCode 的 settings.json 中

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

    【讨论】:

    • 拼写错误pylint_flask_sqlalcheny应该是pylint_flask_sqlalchemy
    【解决方案7】:

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

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

    【讨论】:

      【解决方案8】:

      这是 joeforker 的答案的一个版本,它在 lint 时将 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
      

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

        • 这不是答案!这样做只会完全禁用 pylint(并且静默)。
        【解决方案10】:

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

        【讨论】:

          【解决方案11】:

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

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

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

          3. 如果你没有安装 flake8 作为 pylint 的 VScode 扩展,它会提示你安装它。继续并安装它。

          【讨论】:

            【解决方案12】:

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

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

            【讨论】:

            • 这是解决方案,因为query只会在运行时添加。
            【解决方案13】:

            这就是我处理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中加载​​)

            【讨论】:

              猜你喜欢
              • 2019-01-12
              • 2015-07-26
              • 2017-09-02
              • 2022-01-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多