5

这是我在 sqlalchemy 中使用的一些非常简单的代码,我在这里缺少一些关于类如何工作的基本内容。

class Game(Base):
    __tablename__ = "games"

    id = Column(Integer, primary_key=True)
    a_name = Column(String)

    def __init__(self, **kwargs):
        for k, v in kwargs.iteritems():
             setattr(self, k, v)
        print 'hi'
        self.away_dictionary =  {'name': self.a_name}

    @hybrid_property
    def stuff(self):
        return self.away_dictionary

以下查询有效:

session.query(Game).first().a_name

但以下查询返回错误:

session.query(Game).first().stuff
'Game' object has no attribute 'away_dictionary'

我还有一个更基本的问题,当我查询 Game 类时,它不会打印出“hi”。那么有人可以解释为什么每次我使用游戏实例时都没有打印出'hi'吗?第二个问题是如何为此类的每个实例构建和访问我想拥有的 away_dictionary?

4

4 回答 4

1

啊哈。我正要指出,stuff没有被找到是很奇怪的,我希望away_dictionary不会被找到……你编辑了你的帖子并更改了你引用的错误消息。确实away_dictionary没有找到它,因为它通常是在您的类的__init__()方法中创建的并且__init__()没有被调用。

通常,__init__()会在您创建实例时调用,但是当您在 SQLAlchemy 的查询中使用该类时,它会跳过该__init__()方法。我怀疑这与 SQLAlchemy 的declarative_mapper工作方式有关,但是我对 SQLAlchemy 已经生疏了,以至于我不知道如何修复它。如果我发现了,我稍后会编辑这个答案并告诉你。

但是现在,您可能不应该依赖在__init__()您的 SQLAlchemy 模型对象中调用您的方法(即任何从Base. 看看你是否可以用其他方式来构建你的代码。

于 2013-06-23T01:41:37.793 回答
1

感谢您的评论。只是我还是 sqlalchemy 有点令人困惑?

无论如何,正如人们在上面指出的那样,__init__当您进行查询时,显然不会调用该方法。

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

解决方案是添加以下代码:

from sqlalchemy.orm import reconstructor
@reconstructor
awesome_true_init(self):
    self.away_dictionary = {'hi': 'i work!!'}

这个函数将像一个真实的函数一样__init__在你创建对象时被调用!!

于 2013-06-23T03:40:03.150 回答
0

您没有在上面的查询中创建 Game 实例,您只传递了 Game 类对象。因此init () 构造函数永远不会被调用。如果你需要一个 Game 实例进行查询,你需要这个:session.query(Game()).first().stuff.

于 2013-06-23T00:42:25.350 回答
-2

原因 session.query(Game).first().a_name有效,但session.query(Game).first().stuff不是一个简单的句法问题。a_name 是一个变量,是 Game 类的一个属性,因此您只需键入 a_name 即可引用它。另一方面, stuff 是该类的一个方法,因此您需要在它后面加上一对括号,即使在这种情况下,它们里面没有任何东西。所以尝试使用session.query(Game).first().stuff().

没有打印“hi”,因为只有在使用该构造函数创建对象时才调用init ,而该查询没有执行。

于 2013-06-23T00:47:44.600 回答