11

我有以下代码:

session = scoped_session(sessionmaker(autocommit=False, autoflush=True, bind=engine))

Base = declarative_base()
Base.query = session.query_property()

class CommonBase(object):
  created_at = Column(DateTime, default=datetime.datetime.now)
  updated_at = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)

class Look(Base, CommonBase):
  __tablename__ = "looks"
  id = Column(Integer, primary_key=True)

  def __init__(self):
    print "__init__ is run"
    Base.__init__(self)
    self.feedback = None

  def set_feedback(self, feedback):
    """Status can either be 1 for liked, 0 no response, or -1 disliked.
    """
    assert feedback in [1, 0, -1]
    self.feedback = feedback

  def get_feedback(self):
    return self.feedback

我收到以下错误:

Traceback (most recent call last):
  File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__
    return self.wsgi_app(environ, start_response)
  File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1689, in wsgi_app
    response = self.make_response(self.handle_exception(e))
  File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1687, in wsgi_app
    response = self.full_dispatch_request()
  File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1360, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1358, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Volumes/Data2/Dropbox/projects/Giordano/venv/lib/python2.7/site-packages/flask/app.py", line 1344, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/backend.py", line 94, in wrapped
    ret = f(*args, **kwargs)
  File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/backend.py", line 81, in decorated
    return f(*args, **kwargs)
  File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/web/backend.py", line 187, in next
    json_ret = ge.encode(results)     # automatically pulls the tags
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
  File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/__init__.py", line 54, in default
    jsonable = self.convert_to_jsonable(obj)
  File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/__init__.py", line 40, in convert_to_jsonable
    image_url=obj.image_url, feedback=obj.get_feedback())
  File "/Volumes/Data2/Dropbox/projects/Giordano/src/giordano/models.py", line 100, in get_feedback
    return self.feedback
AttributeError: 'Look' object has no attribute 'feedback'

在我看来,我的__init__方法没有运行,因为我在日志中看不到任何打印语句。

有人可以解释为什么我__init__没有运行,我该怎么做?

4

1 回答 1

30

查看有关重建的 SQLAlchemy 文档

__init__从数据库行重新创建对象时,SQLAlchemy ORM 不会调用。ORM 的过程有点类似于 Python 标准库的 pickle 模块,调用低级__new__ 方法,然后直接在实例上悄悄恢复属性,而不是调用__init__.

如果您需要在数据库加载实例准备好使用之前对其进行一些设置,您可以使用 @reconstructor 装饰器将方法标记为__init__. SQLAlchemy 将在每次加载或重建您的一个实例时不带参数地调用此方法。这对于重新创建通常在您的 中分配的瞬态属性很有用__init__

from sqlalchemy import orm

class MyMappedClass(object):
    def __init__(self, data):
        self.data = data
        # we need stuff on all instances, but not in the database.
        self.stuff = []

    @orm.reconstructor
    def init_on_load(self):
        self.stuff = []

当执行 obj = MyMappedClass() 时,Python__init__ 正常调用该方法并且需要 data 参数。在查询操作期间加载实例时,如在 query(MyMappedClass).one() init_on_load中调用。

于 2013-04-22T21:38:02.460 回答