web-dev-qa-db-ja.com

PylintはSQLAlchemyクエリメンバーを見つけることができません

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)

すべてのクエリ呼び出しで非メンバーエラーを無視することなく、この問題を解決する方法はありますか?


フラスコブートストラップ:

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()
41
Pedro Teixeira

溶液

  1. pip install pylint-flask
  2. インストールされたプラグインをロードします。

    たとえば、VSコードを使用する場合は、setting.jsonファイルを次のように編集してください([ファイル]> [設定]> [設定]コマンドwithで開き、settings.jsonを検索すると、オプションの1つで編集できます)

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

オプション

他の警告がある場合は、pylintrcファイルのgenerated-membersに残りのメンバーを定義します

28
Jun

db.Modelから継承すると宣言したクラスは、コードが実行されるまでqueryメンバーを持たないため、Pylintはそれを検出できません。

すべてのquery呼び出しで非メンバーエラーを無視することに加えて、これの回避策は、Pylint構成ファイルのgenerated-membersリストにqueryを追加することです。実行時に作成されます。

Pylintを実行すると、 documentation に記載されているように構成ファイルが検索されます:

--rcfileオプションを使用して、コマンドラインで設定ファイルを指定できます。それ以外の場合、Pylintは次の順序で構成ファイルを検索し、最初に見つかったものを使用します。

  1. pylintrcは現在の作業ディレクトリにあります
  2. 現在の作業ディレクトリがPythonモジュールにある場合、Pylintはpylintrcファイルが見つかるまでPythonモジュールの階層を検索します。これにより、コーディングを指定できます。モジュールごとの標準。もちろん、ディレクトリは__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.
17
0rkan

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.
15
axis

これらのオプション、プラグインの多くを試し、クエリとすべてを追加した後。それらのscoped_sessionエラーを消去した唯一の解決策は、以下を使用することでした:

  1. pylint --generate-rcfile > pylintrc
  2. ignore_classesを探し、カンマの後にscoped_sessionを追加します。スペースは残しません
  3. モジュールでpylintを再度実行します。
6
Sibo Donald

以下は、いくつかの有名なメソッド名をハードコーディングする代わりに、Sessionオブジェクトのすべてのパブリックメソッドをscoped_sessionのローカルに動的に追加するjoeforkerの回答のバージョンです。

{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
6
Kurtiss Hare

私のために働いたのはflake8 python linterに切り替えることでした。以下は手順です:

  1. VSCodeを開き、Ctrl+shift+P(Windowsユーザーの場合)を実行します
  2. VSCode検索プロンプトで、Python:Select Linterと入力します。すべてのリンターのリストが表示され、flake8が選択されます。
  3. PylintのVScode拡張としてflake8がインストールされていない場合、インストールするように求められます。続行してインストールします。
3
Emz Amechu

別の選択肢は、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
1
jojonas

このページの最初のソリューションでは、以下を更新する必要があります。タイプミスの問題、

の代わりに "pylint_flask"このsettings.jsonパラメーター(この行:"python.linting.pylintArgs": ["--load-plugins", "pylint_flask"]) そのはず "pylint-flask"

1
Saravana Kumar

多くの調査の後、私はPylintにこのメンバーを理解させることができなかったので、querygenerated-membersリストに追加しただけで、チェックは無視されます。

これは完璧なソリューションではありませんが、機能します。

0
Pedro Teixeira

これが、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にロードします)

0
joeforker