2015-01-28 17 views
12

Tôi có một ứng dụng Flask (v0.10.1) sử dụng Flask-SQLAlchemy (v2.0) và tôi đang cố định cấu hình Pylint để kiểm tra nó. Chạy với Python 3.4.2.Pylint không thể tìm thấy thành viên truy vấn SQLAlchemy

lỗi Đầu tiên là:

Instance of 'SQLAlchemy' has no 'Table' member (no-member) 

Và tôi cố định này bỏ qua việc kiểm tra cho thành viên thuộc tính trên SQLAlchemy:

ignored-classes=SQLAlchemy 

Nhưng tôi đang gặp một vấn đề với các thành viên truy vấn trên thực thể:

Class 'UserToken' has no 'query' member (no-member) 

Có cách nào để khắc phục vấn đề này mà không phải bỏ qua thành viên không có thành viên rs trên mọi cuộc gọi truy vấn?


Flask bootstrap:

from flask import Flask 
from flask_sqlalchemy import SQLAlchemy 

db = SQLAlchemy() 
app = Flask(__name__) 
db.init_app(app) 
app.run() 

UserToken thực thể:

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) 

Bộ điều khiển:

from entities import UserToken 

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

Bạn có thể hiển thị phần nào của mã có vi phạm được phát hiện không? – alecxe

+0

Tôi vừa cập nhật mô tả để bao gồm mã. –

+0

Hãy thử sử dụng 'flake8' để thay thế. 'pylint' không được các nhà bảo trì Flask xem xét thuận lợi: https://github.com/mitsuhiko/flask/issues/1312#issuecomment-71837968. Về cơ bản, có rất nhiều thứ năng động đang diễn ra trong Flask-SQLAlchemy, và pylint không nên phàn nàn về nó ngay từ đầu. – davidism

Trả lời

0

Sau rất nhiều cuộc điều tra tôi đã không thể làm cho pylint để hiểu thành viên này, vì vậy tôi chỉ là dded query vào danh sách generated-members và kiểm tra được bỏ qua.

Nó không phải là một giải pháp hoàn hảo nhưng nó hoạt động.

+0

Đây là giải pháp vì 'truy vấn' sẽ chỉ được thêm vào khi chạy. – 0rkan

9

Bất kỳ lớp nào bạn khai báo là kế thừa từ db.Model sẽ không có thành viên query cho đến khi mã chạy để Pylint không thể phát hiện ra nó.

Cách giải quyết khác ngoài việc bỏ qua lỗi không có thành viên trên mỗi cuộc gọi query là thêm query vào danh sách generated-members trong tệp cấu hình Pylint vì nó là thành viên sẽ chỉ được tạo khi chạy.

Khi bạn chạy pylint, nó sẽ tìm kiếm một tập tin cấu hình như đã nêu trong documentation của nó:

Bạn có thể chỉ định một tập tin cấu hình trên dòng lệnh bằng cách sử dụng tùy chọn rcfile. Nếu không, pylint tìm kiếm một tập tin cấu hình theo trình tự sau và sử dụng đầu tiên mà nó tìm thấy:

  1. pylintrc trong thư mục làm việc hiện tại
  2. Nếu thư mục làm việc hiện nay là trong một mô-đun Python, pylint tìm kiếm lên phân cấp các mô-đun Python cho đến khi nó tìm thấy tệp pylintrc. Điều này cho phép bạn chỉ định các tiêu chuẩn mã hóa trên cơ sở từng module.Tất nhiên, một thư mục được đánh giá là một mô-đun Python nếu nó có chứa một tập tin __init__.py
  3. Các tập tin được đặt tên bởi biến môi trường PYLINTRC
  4. nếu bạn có một thư mục home mà không phải là /root:
    1. .pylintrc trong thư mục home của bạn
    2. .config/pylintrc trong thư mục chính của bạn
  5. /etc/pylintrc

Vì vậy, nếu bạn không có cấu hình và bạn muốn cấu hình mặc định cho toàn bộ hệ thống, bạn có thể sử dụng pylint --generate-rcfile > /etc/pylintrc. Điều này sẽ tạo ra một tập tin cấu hình nhận xét theo cấu hình hiện tại (hoặc mặc định nếu bạn không có) mà bạn có thể chỉnh sửa theo sở thích của bạn.

P.S .: generated-members trên một tập tin cấu hình là đúng cách để đối phó với cảnh báo này, vì nó đã nói bởi các cấu hình nhận xét

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

Bạn có nghĩa là thêm tất cả các thành viên đã sử dụng của sql_alchemy là cách chính xác để đối phó với điều này? Đây là cả hai tẻ nhạt và có thể che giấu cảnh báo hơn nữa của tên thành viên tương tự của các lớp khác nhau. Không phải là cách tốt nhất theo ý kiến ​​của tôi. –

4

tôi gặp vấn đề tương tự khi sử dụng flask_sqlalchemy. giải pháp của tôi là:

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

và sau đó tìm dòng

ignored-modules 

, viết lại nó để:

ignored-modules=flask_sqlalchemy 

tất cả E1101 lỗi đã mất hết.

Hãy nhớ để đọc những nhận xét:

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

Đây là cách tôi đối phó với vấn đề này cho scoped_session. Không đáng kể để mở rộng để kiểm tra thêm các tên cls có thuộc tính 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) 

Chuyển thể từ https://docs.pylint.org/en/1.6.0/plugins.html. Sau đó, đảm bảo pylint tải plugin của bạn.

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

(hoặc tải nó trong pylintrc)

0

Một lựa chọn khác là thêm scoped_session vào danh sách các lớp học bỏ qua:

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

Dưới đây là một phiên bản của câu trả lời joeforker rằng động thêm tất cả các phương thức công khai từ đối tượng Session trở lại thành một địa phương của scoped_session tại thời điểm lint, thay vì hardcoding một vài tên phương thức nổi tiếng.

Xác định {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) 

Và trong tập tin .pylintrc của bạn:

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

Tôi vừa thử và nó hoạt động hoàn hảo – diegueus9

0

Sau khi thử rất nhiều các tùy chọn này, bổ sung và thêm truy vấn và tất cả. Giải pháp duy nhất mà xoá hoàn toàn những lỗi scoped_session đã sử dụng:

  1. pylint --generate-rcfile > pylintrc
  2. nhìn cho ignored_classes và thêm scoped_session sau dấu phẩy, để lại không gian
  3. Run pylint trên mô-đun của bạn một lần nữa.
Các vấn đề liên quan