我在使用ZODB LockError
时遇到问题,但是我相信我只能通过一个进程在数据库上进行操作。
我对项目的目标是仅拥有两个功能,load_project()
和save_project()
,该功能允许用户加载Project
对象,对其进行处理,然后与{ {1}},而用户不必直接与ZODB交互。有点像他们只是在处理文档并随其保存。
但是,我注意到我一直在获取save_project()
:可以加载对象,保存一次,但是随后每次尝试保存LockError
时,我都会得到LockError
。显然,对于ZODB的工作方式,我做错了或不了解。 如何防止这种LockError
?
SO上的所有其他LockError问题似乎都涉及多个过程。我正在通过Jupyter Notebook与代码进行交互,我相信这只是一个过程。当我遇到LockError时,我可以重新启动内核(从而开始一个新进程),加载项目,然后再次保存它。 但是后来,我无法再次保存它。
这是我从functions
模块导入的两个函数的代码:
def save_project(project: BIMProject):
"""
Commits the project to the ZODB; including opening and closing the connection
"""
if not hasattr(project, "filename"):
project.filename = input("Enter a filename (without extension):")
if not hasattr(project, "filepath"):
tk_root = Tk()
tk_root.withdraw()
project.filepath = filedialog.askdirectory(title="Please select a directory")
filename = project.filename
full_path = project.filepath + "/" + filename
storage=FileStorage(full_path)
db=ZODB.DB(storage)
connection=db.open()
root=connection.root()
if 'project' in root:
root.update({'project': project})
else:
root['project'] = project # reassign to change
transaction.commit()
connection.close()
def load_project():
"""
Loads a project from a database file
"""
tk_root = Tk()
tk_root.withdraw()
filepath = filedialog.askopenfilename(title="Please select a database file")
storage = FileStorage(filepath)
db = ZODB.DB(storage)
connection = db.open()
root = connection.root()
project = copy.deepcopy(root["project"])
connection.close()
db.close()
return project
任何帮助将不胜感激。
答案 0 :(得分:0)
因此,在我的头上碰壁了一天之后,我散步了,并决定一个对象而不是仅通过函数访问数据库,而是更适合维护与文件存储和数据库的连接。不完全是我所想像的,但是效果很好。
class LoaderSaver:
"""
A 'hang around' object to use in conjunction with Project objects to save them
in a ZODB FileStorage. Carries the ZODB storage, db, and connection objects once
they are opened.
Only one Project file can be open at one time.
"""
def __init__(self):
self.storage = None
self.db = None
self.connection = None
self.root = None
def load(self):
"""
Returns a Project object stored in a ZODB file storage. File selected by
user in a graphical 'file dialog' interface.
"""
tk_root = Tk()
tk_root.withdraw()
filepath = filedialog.askopenfilename(title="Please select a database file")
self.storage = FileStorage(filepath)
self.db = ZODB.DB(self.storage)
self.connection = self.db.open()
self.root = self.connection.root()
project = copy.deepcopy(self.root["project"])
self.connection.close()
return project
def save(self, project: Project):
"""
Commits the project to the ZODB
"""
if not hasattr(project, "filename"):
project.filename = input("Enter a filename (without extension):")
if not hasattr(project, "filepath"):
tk_root = Tk()
tk_root.withdraw()
project.filepath = filedialog.askdirectory(title="Please select a directory")
filename = project.filename
full_path = project.filepath + "/" + filename
if not (self.storage and self.db):
self.storage=FileStorage(full_path)
self.db=ZODB.DB(self.storage)
else:
self.connection=self.db.open()
self.root=self.connection.root()
self.root['project'] = project
transaction.commit()
self.connection.close()