Oli*_*ver 3 python database sqlalchemy flask
我有一个烧瓶应用程序,我做了一堆所有关系相互关联的类:
用户课程讲义笔记队列资产
所以我正在尝试做一个新的讲座和笔记,我为每件事都定义了一个方法.
def createPad(user,course,lecture):
lecture.queues.first().users.append(user)
# make new etherpad for user to wait in
newNote = Note(dt) # init also creates a new pad at /p/groupID$noteID
db.session.add(newNote)
#db.session.commit()
# add note to user, course, and lecture
user.notes.append(newNote)
course.notes.append(newNote)
lecture.notes.append(newNote)
db.session.commit()
return newNote
Run Code Online (Sandbox Code Playgroud)
def createLecture(user, course):
# create new lecture
now = datetime.now()
dt = now.strftime("%Y-%m-%d-%H-%M")
newLecture = Lecture(dt)
db.session.add(newLecture)
# add lecture to course, add new queue to lecture, add user to queue, add new user to lecture
course.lectures.append(newLecture)
newQueue = MatchQueue('neutral')
db.session.add(newQueue)
newLecture.users.append(user)
# hook up the new queue to the user, lecture
newQueue.users.append(user)
newQueue.lecture = newLecture
# put new lecture in correct course
db.session.commit()
newLecture.groupID = pad.createGroupIfNotExistsFor(newLecture.course.name+dt)['groupID']
db.session.commit()
return newLecture
Run Code Online (Sandbox Code Playgroud)
这是从一些控制器逻辑调用的
newlec = createLecture(user, courseobj)
# make new pad
newNote = createPad(user,courseobj,newlec)
# make lecture live
newLecture.live = True
db.session.commit()
redirect(somewhere)
Run Code Online (Sandbox Code Playgroud)
这最终会抛出这个错误:
ObjectDereferencedError:无法为属性'Queue.users'发出更改事件 - 类型的父对象已被垃圾回收.
在lecture.queues.first().users.append(user)
在createPad
.
我不知道这意味着什么.我想我在这里缺乏一些关于sqlalchemy的基本知识(我是一个sqlalchemy noob).这是怎么回事?
lecture.queues.first().users.append(user)
Run Code Online (Sandbox Code Playgroud)
它的意思是:
第一个()方法命中数据库并生成一个对象,我没有关注你的映射,但我猜它是一个Queue对象.
然后,您访问Queue上的"users"集合.
此时,Python本身垃圾收集队列 - 一旦"用户"被返回,它就不会被引用到任何地方.这是引用计数垃圾收集的工作原理.
然后,您尝试将"用户"附加到"用户".SQLAlchemy必须跟踪对所有映射属性的更改,如果你说Queue.name = "some name"
,SQLAlchemy需要在父Queue
对象中注册它,以便它知道要刷新它.如果你说Queue.users.append(someuser)
同样的想法,它需要向父母注册变更事件.
SQLAlchemy无法做到这一点,因为Queue
它已经消失了.因此提出了这个消息.SQLAlchemy 在这里对父项有一个弱参数,因此它确切地知道发生了什么(我们无法阻止它,因为当我们在对象模型中创建不必要的引用循环时,人们会非常沮丧).
解决方案非常简单,也更容易阅读,即将查询结果分配给变量:
queue = lecture.queues.first()
queue.users.append(user)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
815 次 |
最近记录: |