使用SQLAlchemy时出现'NoneType'对象没有'get'属性错误

5 投票
2 回答
8642 浏览
提问于 2025-04-15 21:24

我一直在尝试用SQLAlchemy把一个对象映射到数据库,但遇到了一些问题。

Edit: Basically changed a whole bunch of stuff.

版本信息: [操作系统:Mac OSX 10.5.8 | Python: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在字典中的工作方式有什么关系吗?

2 个回答

0

看起来你可能遇到了一个名字冲突的问题,也就是说Column('id'...)这个名字把Student.id给遮住了。你可以试着把Student.__init__.id改成Student.__init__.sid,这样可以快速确认这个猜测是否正确。

SQLAlchemy的映射教程的第三个代码块中提到了这个连接。

比如,你可以用下面这段代码替换你最开始的代码片段:

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

显然,其他地方提到的Student.id也需要相应地进行修改。

2

你在创建Student实例的时候,应该先把类转换成SQLAlchemy需要的格式。现在你的实例没有正确初始化。只需要把创建Student实例的代码放在调用mapper(Student, students_table)之后,这样一切就会正常工作了。

撰写回答