2013-06-26 19 views
7

Tôi có một dự án cần tây được kết nối với cơ sở dữ liệu MySQL. Một trong các bảng được định nghĩa như thế này:Celery and SQLAlchemy - Đối tượng kết quả này không trả về các hàng. Nó đã được đóng tự động

class MyQueues(Base): 
    __tablename__ = 'accepted_queues' 

    id = sa.Column(sa.Integer, primary_key=True) 
    customer = sa.Column(sa.String(length=50), nullable=False) 
    accepted = sa.Column(sa.Boolean, default=True, nullable=False) 
    denied = sa.Column(sa.Boolean, default=True, nullable=False) 

Ngoài ra, trong các thiết lập tôi có

THREADS = 4 

Và tôi bị mắc kẹt trong một hàm trong code.py:

def load_accepted_queues(session, mode=None): 

    #make query 
    pool = session.query(MyQueues.customer, MyQueues.accepted, MyQueues.denied) 

    #filter conditions  
    if (mode == 'XXX'): 
     pool = pool.filter_by(accepted=1) 
    elif (mode == 'YYY'): 
     pool = pool.filter_by(denied=1) 
    elif (mode is None): 
     pool = pool.filter(\ 
      sa.or_(MyQueues.accepted == 1, MyQueues.denied == 1) 
      ) 

    #generate a dictionary with data 
    for i in pool: #<---------- line 90 in the error 
     l.update({i.customer: {'customer': i.customer, 'accepted': i.accepted, 'denied': i.denied}}) 

Khi chạy này Tôi gặp lỗi:

[20130626 115343] Traceback (most recent call last): 
    File "/home/me/code/processing/helpers.py", line 129, in wrapper 
    ret_value = func(session, *args, **kwargs) 
    File "/home/me/code/processing/test.py", line 90, in load_accepted_queues 
    for i in pool: #generate a dictionary with data 
    File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2341, in instances 
    fetch = cursor.fetchall() 
    File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 3205, in fetchall 
    l = self.process_rows(self._fetchall_impl()) 
    File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 3174, in _fetchall_impl 
    self._non_result() 
    File "/home/me/envs/me/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 3179, in _non_result 
    "This result object does not return rows. " 
ResourceClosedError: This result object does not return rows. It has been closed automatically 

Vì vậy, chủ yếu nó là phần

ResourceClosedError: This result object does not return rows. It has been closed automatically 

và đôi khi cũng lỗi này:

DBAPIError: (Error) (, AssertionError('Result length not requested length:\nExpected=1. Actual=0. Position: 21. Data Length: 21',)) 'SELECT accepted_queues.customer AS accepted_queues_customer, accepted_queues.accepted AS accepted_queues_accepted, accepted_queues.denied AS accepted_queues_denied \nFROM accepted_queues \nWHERE accepted_queues.accepted = %s OR accepted_queues.denied = %s' (1, 1)

tôi không thể tái tạo các errror đúng vì nó thường xảy ra khi xử lý nhiều dữ liệu. Tôi đã cố gắng thay đổi THREADS = 4 thành 1 và các lỗi biến mất. Dù sao, nó không phải là một giải pháp vì tôi cần số lượng các chủ đề được giữ trên 4.

Ngoài ra, tôi đang bối rối về sự cần thiết phải sử dụng

for i in pool: #<---------- line 90 in the error 

hoặc

for i in pool.all(): #<---------- line 90 in the error 

và không thể tìm thấy một lời giải thích hợp của nó.

Tất cả cùng nhau: bất kỳ lời khuyên nào để bỏ qua những khó khăn này?

Trả lời

10

All together: any advise to skip these difficulties?

có. bạn hoàn toàn không thể sử dụng Phiên (hoặc bất kỳ đối tượng nào được liên kết với Phiên đó) hoặc Kết nối, trong nhiều hơn một luồng cùng một lúc, đặc biệt là với MySQL-Python có kết nối DBAPI rất không an toàn *. Bạn phải tổ chức ứng dụng của bạn sao cho mỗi luồng giao dịch với kết nối MySQL-Python riêng của nó (và do đó kết nối SQLAlchemy/Session/các đối tượng liên quan đến Session đó) mà không có sự rò rỉ cho bất kỳ luồng nào khác.

  • Chỉnh sửa: cách khác, bạn có thể sử dụng mutexes để giới hạn quyền truy cập vào kết nối phiên/kết nối/DBAPI chỉ với một trong các chủ đề đó, mặc dù điều này ít phổ biến hơn. để đánh bại mục đích sử dụng nhiều luồng ở vị trí đầu tiên.
+0

Uhm, do đó, đây là vấn đề với chủ đề và đồng thời ... Điều này đang mở ra nhiều khả năng tôi không chắc mình biết cách xử lý. Có cách nào cụ thể để bắt đầu làm việc với một luồng cùng một lúc không? Làm thế nào tôi có thể theo dõi thread nào đang làm gì? Bất kỳ gợi ý sẽ được đánh giá cao! – fedorqui

+2

Nếu bạn định sử dụng các chủ đề, bạn cần phải nắm vững một hoặc cả hai kỹ thuật cơ bản - nhận được mỗi luồng để chia sẻ không có trạng thái nào hoặc sử dụng mutexes/locks xung quanh tài nguyên được chia sẻ, không an toàn sao cho chỉ có một sợi chỉ chạm vào nó. Với SQLAclhemy, trường hợp sử dụng "không chia sẻ bất cứ điều gì" thường được giải quyết bằng cách sử dụng [scoped_session] (http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html?highlight = scoped_session # unitofwork-contextual) xây dựng. Nhưng nó rất hữu ích nếu bạn có một nắm vững về những gì một "thread biến địa phương" là và những gì có nghĩa là. – zzzeek

+0

Tuyệt vời. Tôi phải cải thiện mã tôi đã được đưa ra, vì vậy để làm theo lời khuyên có giá trị của bạn, tôi thực sự cần thêm kiến ​​thức về các chủ đề và các phiên. Tôi đã tìm kiếm một tài liệu cấp độ toàn diện và từ số không và tìm thấy http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html. Khi bạn biết chủ đề này nhiều hơn bất cứ ai, bạn có thể đề xuất bất kỳ điểm khởi đầu nào khác có thể không? Cảm ơn rất nhiều, @zzzeek! – fedorqui

Các vấn đề liên quan