【问题标题】:Retrieve Method Issue? AttributeError Complaining about 'str' object检索方法问题? AttributeError 抱怨“str”对象
【发布时间】:2015-10-02 16:32:45
【问题描述】:

问题:AttributeError: 'str' object has no attribute '_sa_instance_state',我不确定如何解决它。 我相信它与下面的retrieve 方法有关。 Stacks 上的某个人遇到了类似的问题,更改功能很简单……这对我来说并非如此。

追溯:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/Users/ack/code/venv/NotssDB/notssdb/test/test.py", line 132, in test1
    api.retrieve_assessment_result('baseball', 'Becoming a Leader')
  File "/Users/ack/code/venv/NotssDB/notssdb/api/object.py", line 324, in retrieve_assessment_result
    filter(Assessment_Result.owner == owner).one()
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/sql/operators.py", line 301, in __eq__
    return self.operate(eq, other)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 175, in operate
    return op(self.comparator, *other, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 1011, in __eq__
    other, adapt_source=self.adapter))
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 1338, in _optimized_compare
    state = attributes.instance_state(state)
AttributeError: 'str' object has no attribute '_sa_instance_state'

object.py

def retrieve_assessment_result(self, *args):
    id, owner, assessment = None, None, None
    if len(args) == 1:
        id, = args[0]
    elif len(args) == 2:
        owner, assessment = args
    else:
        raise ValueError('Value being passed is an object')
    if id is not None:
        return self.session.query(Assessment_Result).\
        filter(Assessment_Result.id == id).one()
    elif owner is not None:
        print 'test1', owner
        return self.session.query(Assessment_Result).\
        filter(Assessment_Result.owner == owner).one()
    elif assessment is not None:
        print 'test2', assessment
        return self.session.query(Assessment_Result).\
        filter(Assessment_Result.assessment == assessment).one()

def create_category_rating(self, category_rating_int, category, assessment_result):
    new_catrating = Category_Rating(category_rating_int, category, assessment_result)
    self.session.add(new_catrating)
    print(new_catrating)
    self.session.commit()
    return(new_catrating)

convenience.py (继承自object.py)

def create_category_rating(self, category_rating_int, category_name, username, name):
    category = self.retrieve_category(category_name)
    owner = self.retrieve_user(username)  
    assessment = self.retrieve_assessment(name)  
    assessment_result = self.retrieve_assessment_result(owner, assessment)
    return super(ConvenienceAPI, self).create_category_rating(category_rating_int, category, assessment_result)

模型.py

class Category_Rating(Base):
    __tablename__ = 'category_ratings'

    id = Column(Integer, primary_key=True)
    category_rating_int = Column(Integer)

    category_id = Column(Integer, ForeignKey('categories.category_id'))
    category = relationship('Category', backref='category_ratings')

    assessment_result_id = Column(Integer, ForeignKey('assessment_results.id'))
    assessment_result = relationship('Assessment_Result', backref='category_ratings')

    def __init__(self, category_rating_int, category, assessment_result): #OBJECT
        self.category_rating_int = category_rating_int
        self.category = category
        self.assessment_result  = assessment_result

    def __repr__(self):
        return "<Category_Rating(category_rating_int='%s')>" % (self.category_rating_int)

test.py

api = ConvenienceAPI()
api.create_category_rating(2, 'Decision-Making', 'baseball', 'Becoming a Leader')

【问题讨论】:

  • 请包括minimal, complete, verifiable example,包括您的模型定义。所以人们可以重现你的错误。还包括您在调用create_category_rating(...) 时作为参数传递的值。
  • 您阅读过链接问题的解释吗?问题是没有改变功能。它清楚地解释了什么是问题:“您正在将列表分配给uselist=False 的关系。您应该设置单个模型实例,而不是包含它的列表。”。当您创建 Category_Rating 实例时,您很可能会这样做。
  • @YaroslavAdmin 是的,我有。我现在已经发布了要求的材料。我正在努力理解自己,因为我对这一切都是新手。

标签: python sqlalchemy traceback


【解决方案1】:

您的问题与链接问题中的问题完全相同:

您正在为uselist=False 的关系分配一个列表。您应该设置单个模型实例,而不是包含它的列表。

在您的情况下,属性 assessment_results 被定义为多对一关系(例如,单个 Category_Rating 可以有单个 Assessment_Results 实例,但单个 Assessment_Results 可以有 多个 @987654328 @ 实例)。如果您执行以下重命名,则以前的语句对您来说会更有意义:

assessment_results -> assessment_result
assessment_results_id -> assessment_result_id
Assessment_Results -> Assessment_Result

问题在于assessment_results 属性需要Assessment_Results 模型的单个实例,但是您将其设置为方法retrieve_assessment_results() 的结果,该方法返回Assessment_Results 的列表。这就是它失败的原因。

UPD

第二个问题在这个字符串filter(Assessment_Result.owner == owner).one() 中。您尝试将 Owner 实例与字符串进行比较。您可能想用filter(Owner.name == owner).one() 之类的东西替换它。如果没有看到这些模型定义,就无法准确告诉您。

【讨论】:

  • 非常感谢您的解释!谢谢你。澄清一下:Assessment_Results 是一个表格,用于保存每个 Assessment 及其各自的 categories。因此,Assessment_ResultsAssessment_Results 将持有大约 4 个 category_ratings
  • 比我的假设不正确。您无需将关系定义移至 Assessment_Results 模型。只需确保从 retrieve_assessment_results() 方法返回 single 实例即可。根据您的数据结构,使用.one().first() 而不是.all()
  • 我更改了命名约定(以防止误解)所以谢谢你!当我通过.one() 时,它返回AttributeError: 'str' object has no attribute '_sa_instance_state' 所以我可以更新我的问题,以根据您的建议更准确地反映这个问题?
  • 好吧,用新代码更新问题并添加新的回溯。或者你可以自己调试。很可能您将字符串而不是模型分配给关系。
【解决方案2】:

与 Yaroslav Admin 合作,我做了一些与他的建议类似的事情...我在用于检查字符串的便利.py (api) 中为 assessment_result(..) 添加了一个检索方法:

工作代码:
(这继承自 object.py 文件——如上所示)

def retrieve_assessment_result(self, username, name):
    owner = self.retrieve_user(username)
    assessment = self.retrieve_assessment(name)
    return super(ConvenienceAPI, self).retrieve_assessment_result(owner, assessment)

【讨论】:

    猜你喜欢
    • 2019-05-17
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2013-08-14
    相关资源
    最近更新 更多