[Checkins] SVN: z3c.dobbin/trunk/src/z3c/dobbin/ Fixed issue with
incorrect insertion order. Thanks to Michael Bayer for the
guidance on this bug fix.
Malthe Borch
mborch at gmail.com
Thu Jun 12 12:04:46 EDT 2008
Log message for revision 87336:
Fixed issue with incorrect insertion order. Thanks to Michael Bayer for the guidance on this bug fix.
Changed:
U z3c.dobbin/trunk/src/z3c/dobbin/README.txt
U z3c.dobbin/trunk/src/z3c/dobbin/mapper.py
-=-
Modified: z3c.dobbin/trunk/src/z3c/dobbin/README.txt
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/README.txt 2008-06-12 16:02:52 UTC (rev 87335)
+++ z3c.dobbin/trunk/src/z3c/dobbin/README.txt 2008-06-12 16:04:46 UTC (rev 87336)
@@ -103,12 +103,12 @@
[(2, 45)]
>>> session.execute(metadata.tables[encode(IAlbum)].select()).fetchall()
- [(1, u'The Great American Songbook', u'Diana Ross'),
+ [(1, u'Pet Sounds', u'The Beach Boys'),
(2, u'Taking Care of Business', u'Diana Ross and The Supremes'),
- (3, u'Pet Sounds', u'The Beach Boys')]
+ (3, u'The Great American Songbook', u'Diana Ross')]
>>> session.execute(metadata.tables[encode(ICompactDisc)].select()).fetchall()
- [(1, 2005)]
+ [(3, 2005)]
Now we'll create a mapper based on a concrete class. We'll let the
class implement the interface that describes the attributes we want to
@@ -225,7 +225,7 @@
insert it into the database.
>>> cleaner = Accessory()
- >>> cleaner.name = "Record cleaner"
+ >>> cleaner.name = u"Record cleaner"
Set up relation.
@@ -273,7 +273,11 @@
... value_type=schema.Object(schema=IAlbum)
... )
+ >>> __builtin__.ICollection = ICollection
+
>>> collection = create(ICollection)
+ >>> collection.records
+ []
Add the Diana Ross record, and save the collection to the session.
@@ -282,8 +286,8 @@
We can get our collection back.
- >>> collection = session.query(ICollection.__mapper__).select_by(
- ... ICollection.__mapper__.c.spec==ICollection.__mapper__.__spec__)[0]
+ >>> from z3c.dobbin.relations import lookup
+ >>> collection = lookup(collection.uuid)
Let's verify that we've stored the Diana Ross record.
@@ -292,16 +296,25 @@
>>> record.artist, record.title
(u'Diana Ross and The Supremes', u'Taking Care of Business')
-Now let's try and add another record.
+ >>> transaction.commit()
+When we create a new, transient object and append it to a list, it's
+automatically saved on the session.
+
+ >>> collection = lookup(collection.uuid)
+
+ >>> vinyl = create(IVinyl)
+ >>> vinyl.artist = u"Kool & the Gang"
+ >>> vinyl.album = u"Music Is the Message"
+ >>> vinyl.rpm = 33
+
>>> collection.records.append(vinyl)
- >>> another_record = collection.records[1]
+ >>> [record.artist for record in collection.records]
+ [u'Diana Ross and The Supremes', u'Kool & the Gang']
-They're different.
+ >>> transaction.commit()
+ >>> session.update(collection)
- >>> record.uuid != another_record.uuid
- True
-
We can remove items.
>>> collection.records.remove(vinyl)
@@ -382,5 +395,3 @@
Commit session.
>>> transaction.commit()
-
-
Modified: z3c.dobbin/trunk/src/z3c/dobbin/mapper.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/mapper.py 2008-06-12 16:02:52 UTC (rev 87335)
+++ z3c.dobbin/trunk/src/z3c/dobbin/mapper.py 2008-06-12 16:04:46 UTC (rev 87336)
@@ -73,8 +73,6 @@
def adapter(self):
return self._sa_adapter
- # orm collection support
-
@orm.collections.collection.appender
def _appender(self, item):
self.data.append(item)
@@ -87,28 +85,21 @@
def _remover(self, item):
self.data.remove(item)
- # python list api
-
def append(self, item, _sa_initiator=None):
# make sure item is mapped
if not IMapped.providedBy(item):
item = relations.persist(item)
- # fire append event
- self.adapter.fire_append_event(item, _sa_initiator)
-
# set up relation
relation = bootstrap.Relation()
relation.target = item
relation.order = len(self.data)
- # save to session
- session = Session()
- session.save(relation)
-
+ self.adapter.fire_append_event(relation, _sa_initiator)
+
# add relation to internal list
self.data.append(relation)
-
+
def remove(self, item, _sa_initiator=None):
if IMapped.providedBy(item):
uuid = item.uuid
@@ -117,20 +108,12 @@
for relation in self.data:
if relation.right == uuid:
- # fire remove event on target
- target = relations.lookup(uuid, ignore_cache=True)
- self.adapter.fire_remove_event(target, _sa_initiator)
-
- # remove reference to relation
+ self.adapter.fire_remove_event(relation, _sa_initiator)
self.data.remove(relation)
- # delete from database
- session = Session()
- session.delete(relation)
-
return
-
- return ValueError("Not in list: %s" % item)
+ else:
+ return ValueError("Not in list: %s" % item)
def extend(self, items):
map(self.append, items)
@@ -138,6 +121,9 @@
def __iter__(self):
return (relation.target for relation in iter(self.data))
+ def __repr__(self):
+ return repr(list(self))
+
def __len__(self):
return len(self.data)
@@ -293,23 +279,29 @@
# create joined table
soup_table = table = metadata.tables['soup']
properties = {}
+ table = None
for (t, p) in (getTable(iface, metadata, ignore) for iface in ifaces):
- table = rdb.join(table, t, onclause=(t.c.id==soup_table.c.id))
+ if table is None:
+ first_table = table = t
+ else:
+ table = rdb.join(table, t, onclause=(t.c.id==first_table.c.id))
properties.update(p)
- class Mapper(kls):
+ specification_path = '%s.%s' % (spec.__module__, spec.__name__)
+
+ class Mapper(bootstrap.Soup, kls):
interface.implements(IMapped, *ifaces)
- __spec__ = '%s.%s' % (spec.__module__, spec.__name__)
-
+ __spec__ = specification_path
+
def __init__(self, *args, **kwargs):
super(Mapper, self).__init__(*args, **kwargs)
-
+
# set soup metadata
self.uuid = uuid()
self.spec = self.__spec__
-
+
# if the specification is an interface class, try to look up a
# security checker and define it on the mapper
if interface.interfaces.IInterface.providedBy(spec):
@@ -342,7 +334,13 @@
if isinstance(value, property):
exclude += (name,)
- orm.mapper(Mapper, table, properties=properties, exclude_properties=exclude)
+ orm.mapper(
+ Mapper,
+ table,
+ properties=properties,
+ exclude_properties=exclude,
+ inherits=bootstrap.Soup,
+ inherit_condition=(first_table.c.id==soup_table.c.id))
spec.__mapper__ = Mapper
interface.alsoProvides(spec, IMapped)
More information about the Checkins
mailing list