ZODB and COM Server - how to create collection attribute?
Gerhard Kalab
kalab at gmx.net
Sun Aug 26 09:38:34 EDT 2001
I'd like to write a COM-Server and use ZODB for persistence.
The following code doesn't work, because the class Person has a
COM-collection (books) which cannot be pickled.
It would be easy to change the books attribute to get and set COM-methods to
get and set the books list. But is it possible to use a COM-attribute?
Is there any way I can change the books list to a list of normal python
objects before it is going to be saved? And can I change it back to a
COM-collection after the list is loaded by ZODB?
Any other ideas?
Thank you,
Gerhard
#server.py
import ZODB, ZODB.FileStorage
import Persistence
import win32com.client
from win32com.server.util import wrap, unwrap
class Book(Persistence.Persistent):
_public_methods_ = []
_public_attrs_ = ["title"]
def __init__(self):
self.title = ""
class Person(Persistence.Persistent):
_public_methods_ = ["addBook"]
_public_attrs_ = ["name", "books"]
def __init__(self):
self.name = ""
self.books = []
def addBook(self):
b = Book()
wrapped = wrap(b)
self.books.append(wrapped)
self._p_changed = 1
return wrapped
class PRoot(Persistence.Persistent):
def __init__(self):
self.persons = []
def addPerson(self):
p = Person()
self.persons.append(p)
self._p_changed = 1
return wrap(p)
class Root:
_reg_clsid_ = "{D37DE5DB-EFA6-4135-9B85-250D9F988E35}"
_reg_desc_ = "Root"
_reg_progid_ = "Server.Root"
_public_methods_ = ["setConnection", "addPerson", "save"]
_public_attrs_ = ["persons"]
_readonly_attrs_ = ["persons"]
def __init__(self):
self.persons = []
def setConnection(self, storage):
self.storage = ZODB.FileStorage.FileStorage(storage)
self.db = ZODB.DB(self.storage)
self.connection = self.db.open()
self.root = self.connection.root()
get_transaction().begin()
if not self.root.has_key("root"):
self.rootobj = self
self.root["root"] = PRoot()
self.rootobj = self.root["root"]
for p in self.rootobj.persons:
self.persons.append(wrap(p))
def addPerson(self):
p = self.rootobj.addPerson()
self.persons.append(p)
return p
def __del__(self):
self.connection.close()
def save(self):
get_transaction().commit()
if __name__=='__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(Root)
#-----------------
#client.py
from win32com.client import Dispatch
root = Dispatch("Server.Root")
root.setConnection("data.fs")
for name in ["Foo", "Bar"]:
person = root.addPerson()
person.name = name
book = person.addBook()
book.title = "abc"
persons = root.persons
for person in persons:
print person.name
for book in person.books:
print book.title
root.save() #--> fails
More information about the Python-list
mailing list