【问题标题】:'NoneType' object has no attribute 'get' error using SQLAlchemy'NoneType' 对象没有属性 'get' 错误使用 SQLAlchemy
【发布时间】:2010-04-09 05:14:07
【问题描述】:

我一直在尝试使用 SQLAlchemy 将对象映射到数据库,但遇到了障碍。

Edit: Basically changed a whole bunch of stuff.

版本信息(如果方便):[操作系统:Mac OSX 10.5.8 |蟒蛇:2.6.4 | SQLAlchemy:0.5.8]

我要映射的类:

class Student(object):
    def __init__(self, id, name):
        self.id = id
        self.name = name

    def __repr__(self):
        return str(self)

    def __str__(self):
        return "%s %s" %(self.id, self.name)

背景:

现在,我有了一个函数,可以将文本数据库中的必要信息读入这些对象。该功能或多或少有效,我可以轻松访问对象中的信息。

在 SQLAlchemy 代码运行之前,该函数将读入必要的信息并将其存储到类中。有一个名为 students 的字典将其存储为:

students = {}
students[id] = Student(<all the info from the various "reader" functions>)

之后,会有一个“分配”算法将项目分配给学生。它做得很好。如果学生没有成功获得项目,allocated_project 将保留为 None

SQLAlchemy 位:

所以在这一切发生之后,我想将我的对象映射到一个数据库表。

from sqlalchemy import *
from sqlalchemy.orm import *

engine = create_engine('sqlite:///:memory:', echo=False)
metadata = MetaData()
students_table = Table('studs', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String)
)
metadata.create_all(engine)
mapper(Student, students_table)

在那之后,我很想知道是否可以打印出我的学生词典中的所有学生。

for student in students.itervalues():
    print student

除了错误,我得到了什么。仅当尝试按原样打印时才会发生此错误,调用mapper

Traceback (most recent call last):
  File "~/FYP_Tests/FYP_Tests.py", line 140, in <module>
    print student
  File "~/FYP_Tests/Parties.py", line 30, in __str__
    return "%s %s" %(self.id, self.name)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/SQLAlchemy-0.5.8-py2.6.egg/sqlalchemy/orm/attributes.py", line 158, in __get__
  return self.impl.get(instance_state(instance), instance_dict(instance))
AttributeError: 'NoneType' object has no attribute 'get'

如果这是一个问题,我不知道如何解决这个问题。如果需要更多信息,请询问,我会提供。

Questions:
  1. SQLAlchemy mapper 是否改变了原始类/字典的任何内容?
  2. 这对get 使用字典的方式有什么特定的吗?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    您在映射类之前创建 Student 实例,该类修改类以满足 SQLAlchemy 的需求。所以你的实例没有正确初始化。只需在调用mapper(Student, students_table)之后添加创建Student 实例的行,一切都会按预期工作。

    【讨论】:

    • 我想你已经搞定了。当我尝试这种花哨的for students in students.itervalues: session.add(student) 时,我收到一个错误,说明在映射之前创建一个实例。所以,基本上,这部分数据库代码应该放在我开始从文本文件中读取信息之前?
    【解决方案2】:

    看起来您可能存在名称隐藏冲突,其中Column('id'...) 隐藏了 Student.id。将Student.__init__.id 更改为Student._init__.sid 将是确认或反驳此猜想的快速测试。

    SQLAlchemy tutorial on mappings 的第三个代码块中提到了这种连接。

    例如,用这个片段替换你的第一个代码sn-p:

    class Student(object):
        def __init__(self, name, id):
            self.sid = id
            self.name = name
            # and so on
    

    显然,对Student.id 的其他引用也必须更改。

    【讨论】:

    • @msw:会尽力让你知道的。
    • 我添加了“快速测试”这句话来(希望)澄清
    • @msw:仔细检查一下,'self.sid = id' 本质上是做什么的?通常不是'self.something = something'吗? (请注意,我是 Python 初学者) 编辑:试过了。代码仍然有效,但错误消息没有改变。这与allocated_projectNone 的存在有什么关系吗?
    • __getattr__ 的(非常强大,但又有点神秘)语义仍然让我感到困惑。祝你好运。 +1 提出一个很好的问题。
    • self.id = id 是正确的习惯用法,因为我猜想 Column('id' 隐藏了 self.id 我建议快速检查一下。 sid 的唯一含义是它不是 id,它可能是 fred 也可以测试我的猜测。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-14
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 2017-09-14
    相关资源
    最近更新 更多