Pylint can't find SQLAlchemy query member

前端 未结 13 1422
予麋鹿
予麋鹿 2021-01-30 08:25

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.

First error was:



        
相关标签:
13条回答
  • 2021-01-30 08:57

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

    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.
    0 讨论(0)
  • 2021-01-30 08:59

    Use pylint plugin pylint-flask-sqlalchemy

    pip install pylint_flask_sqlalchemy
    

    And in your settings.json of VisualCode

    "python.linting.pylintArgs": ["--load-plugins", "pylint_flask_sqlalcheny"]
    
    0 讨论(0)
  • 2021-01-30 08:59

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

    Define {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 .pylintrc file:

    load-plugins={path}.{to}.pylintplugins
    
    0 讨论(0)
  • 2021-01-30 09:01

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

    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.

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

    (or load it in pylintrc)

    0 讨论(0)
  • 2021-01-30 09:06

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

    0 讨论(0)
  • 2021-01-30 09:07

    Any class you declare as inheriting from db.Model won't have query member until the code runs so Pylint can't detect it.

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

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

    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. pylintrc in 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__.py file
    3. The file named by environment variable PYLINTRC
    4. if you have a home directory which isn’t /root:
      1. .pylintrc in your home directory
      2. .config/pylintrc in your home directory
    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.

    p.s.: generated-members on a config file is the right way to deal with this warning, as it's said by the commented 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.
    
    0 讨论(0)
提交回复
热议问题