[Checkins] SVN: z3c.dobbin/trunk/src/z3c/dobbin/ Tables for minimal
interfaces are now generated exactly once;
this fixes an issue on postgres first appearing in SQLAlchemy 0.4.6
(r4565). Mappers are now polymorphic;
this fixes an issue on SQLite where joins would be reversed.
Malthe Borch
mborch at gmail.com
Wed Jun 18 12:47:38 EDT 2008
Log message for revision 87528:
Tables for minimal interfaces are now generated exactly once; this fixes an issue on postgres first appearing in SQLAlchemy 0.4.6 (r4565). Mappers are now polymorphic; this fixes an issue on SQLite where joins would be reversed.
Changed:
U z3c.dobbin/trunk/src/z3c/dobbin/README.txt
U z3c.dobbin/trunk/src/z3c/dobbin/collections.py
U z3c.dobbin/trunk/src/z3c/dobbin/mapper.py
U z3c.dobbin/trunk/src/z3c/dobbin/relations.py
U z3c.dobbin/trunk/src/z3c/dobbin/session.py
-=-
Modified: z3c.dobbin/trunk/src/z3c/dobbin/README.txt
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/README.txt 2008-06-18 16:44:12 UTC (rev 87527)
+++ z3c.dobbin/trunk/src/z3c/dobbin/README.txt 2008-06-18 16:47:38 UTC (rev 87528)
@@ -131,6 +131,7 @@
>>> import __builtin__
>>> __builtin__.IVinyl = IVinyl
+ >>> __builtin__.IAlbum = IAlbum
>>> __builtin__.Vinyl = Vinyl
Create an instance using the ``create`` factory.
@@ -144,8 +145,8 @@
Copy the attributes from the Diana Ross vinyl record.
- >>> diana = session.query(IVinyl.__mapper__).filter_by(id=2)[0]
-
+ >>> diana = session.query(IVinyl.__mapper__).filter_by(
+ ... artist=u"Diana Ross and The Supremes")[0]
>>> vinyl.artist = diana.artist
>>> vinyl.title = diana.title
>>> vinyl.rpm = diana.rpm
@@ -254,7 +255,10 @@
persisted in the database.
>>> cleaner.name = u"CD cleaner"
- >>> transaction.commit()
+
+ >>> session.flush()
+ >>> session.update(favorite)
+
>>> favorite.item.name
u'CD cleaner'
@@ -285,7 +289,7 @@
We can get our collection back.
- >>> from z3c.dobbin.relations import lookup
+ >>> from z3c.dobbin.soup import lookup
>>> collection = lookup(collection.uuid)
Let's verify that we've stored the Diana Ross record.
@@ -295,7 +299,7 @@
>>> record.artist, record.title
(u'Diana Ross and The Supremes', u'Taking Care of Business')
- >>> transaction.commit()
+ >>> session.flush()
When we create a new, transient object and append it to a list, it's
automatically saved on the session.
@@ -304,14 +308,14 @@
>>> vinyl = create(IVinyl)
>>> vinyl.artist = u"Kool & the Gang"
- >>> vinyl.album = u"Music Is the Message"
+ >>> vinyl.title = u"Music Is the Message"
>>> vinyl.rpm = 33
>>> collection.records.append(vinyl)
>>> [record.artist for record in collection.records]
[u'Diana Ross and The Supremes', u'Kool & the Gang']
- >>> transaction.commit()
+ >>> session.flush()
>>> session.update(collection)
We can remove items.
@@ -383,10 +387,9 @@
... __name__ = schema.TextLine()
>>> from z3c.dobbin.interfaces import IMapper
-
>>> mapper = IMapper(IKnownLimitations)
- >>> '__name__' in mapper.c
- False
+ >>> mapper.__name__
+ 'Mapper'
Cleanup
-------
Modified: z3c.dobbin/trunk/src/z3c/dobbin/collections.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/collections.py 2008-06-18 16:44:12 UTC (rev 87527)
+++ z3c.dobbin/trunk/src/z3c/dobbin/collections.py 2008-06-18 16:47:38 UTC (rev 87528)
@@ -4,6 +4,7 @@
import interfaces
import relations
+import soup
class OrderedList(object):
__Security_checker__ = NamesChecker(
@@ -27,11 +28,12 @@
@orm.collections.collection.remover
def _remover(self, item):
self.data.remove(item)
-
+
+ @orm.collections.collection.internally_instrumented
def append(self, item, _sa_initiator=None):
# make sure item is mapped
if not interfaces.IMapped.providedBy(item):
- item = relations.persist(item)
+ item = soup.persist(item)
# set up relation
relation = relations.Relation()
@@ -43,6 +45,7 @@
# add relation to internal list
self.data.append(relation)
+ @orm.collections.collection.internally_instrumented
def remove(self, item, _sa_initiator=None):
if interfaces.IMapped.providedBy(item):
uuid = item.uuid
Modified: z3c.dobbin/trunk/src/z3c/dobbin/mapper.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/mapper.py 2008-06-18 16:44:12 UTC (rev 87527)
+++ z3c.dobbin/trunk/src/z3c/dobbin/mapper.py 2008-06-18 16:47:38 UTC (rev 87528)
@@ -172,8 +172,8 @@
engine = component.getUtility(IDatabaseEngine)
metadata = engine.metadata
- ignore = ('__name__',)
-
+ exclude = ['__name__']
+
# expand specification
if interface.interfaces.IInterface.providedBy(spec):
ifaces = set([spec.get(name).interface for name in schema.getFields(spec)])
@@ -184,12 +184,16 @@
ifaces = set([implemented.get(name).interface for name in fields])
kls = spec
+ for name, value in spec.__dict__.items():
+ if isinstance(value, property):
+ exclude.append(name)
+
# create joined table
soup_table = table = metadata.tables['soup']
properties = {}
first_table = None
- for (t, p) in (getTable(iface, metadata, ignore) for iface in ifaces):
+ for (t, p) in (getTable(iface, metadata, exclude) for iface in ifaces):
if first_table is None:
table = first_table = t
else:
@@ -197,7 +201,7 @@
properties.update(p)
specification_path = '%s.%s' % (spec.__module__, spec.__name__)
-
+
class Mapper(bootstrap.Soup, kls):
interface.implements(IMapped, *ifaces)
@@ -235,18 +239,17 @@
del properties[name]
setattr(Mapper, name, prop)
- exclude = ()
-
- if not interface.interfaces.IInterface.providedBy(spec):
- for name, value in spec.__dict__.items():
- if isinstance(value, property):
- exclude += (name,)
+ polymorphic = (
+ [Mapper], table.join(
+ soup_table, first_table.c.id==soup_table.c.id))
+
orm.mapper(
Mapper,
table,
properties=properties,
exclude_properties=exclude,
+ with_polymorphic=polymorphic,
inherits=bootstrap.Soup,
inherit_condition=(first_table.c.id==soup_table.c.id))
@@ -260,24 +263,28 @@
interface.noLongerProvides(spec, IMapped)
def getTable(iface, metadata, ignore=()):
+ name = encode(iface)
+
columns = []
properties = {}
for field in map(lambda key: iface[key], iface.names()):
property_factory = None
- # ignores
if field.__name__ in ignore:
continue
-
+
try:
- column_factory, property_factory = fieldmap[type(field)]
- except TypeError:
- column_factory = fieldmap[type(field)]
+ factories = fieldmap[type(field)]
except KeyError:
# raise NotImplementedError("Field type unsupported (%s)." % field)
continue
+ try:
+ column_factory, property_factory = factories
+ except TypeError:
+ column_factory = factories
+
if column_factory is not None:
column = column_factory(field, metadata)
columns.append(column)
@@ -287,11 +294,14 @@
if property_factory is not None:
props = property_factory(field, column, metadata)
properties.update(props)
+
+ if name in metadata.tables:
+ return metadata.tables[name], properties
kw = dict(useexisting=True)
table = rdb.Table(
- encode(iface),
+ name,
metadata,
rdb.Column('id', rdb.Integer, rdb.ForeignKey("soup.id"), primary_key=True),
*columns,
Modified: z3c.dobbin/trunk/src/z3c/dobbin/relations.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/relations.py 2008-06-18 16:44:12 UTC (rev 87527)
+++ z3c.dobbin/trunk/src/z3c/dobbin/relations.py 2008-06-18 16:47:38 UTC (rev 87528)
@@ -18,7 +18,7 @@
def _set_target(self, item):
if not interfaces.IMapped.providedBy(item):
- item = persist(item)
+ item = soup.persist(item)
if item.id is None:
session = Session()
@@ -41,7 +41,7 @@
def set(kls, instance, item):
if not interfaces.IMapped.providedBy(item):
- item = persist(item)
+ item = soup.persist(item)
if item.id is None:
session = Session()
Modified: z3c.dobbin/trunk/src/z3c/dobbin/session.py
===================================================================
--- z3c.dobbin/trunk/src/z3c/dobbin/session.py 2008-06-18 16:44:12 UTC (rev 87527)
+++ z3c.dobbin/trunk/src/z3c/dobbin/session.py 2008-06-18 16:47:38 UTC (rev 87528)
@@ -5,7 +5,7 @@
from ore.alchemist import Session
-import relations
+import soup
class Savepoint:
"""Transaction savepoint."""
@@ -53,10 +53,10 @@
del session._d_pending[uuid]
# build instance
- instance = relations.lookup(uuid)
+ instance = soup.lookup(uuid)
# update attributes
- relations.update(instance, obj)
+ soup.update(instance, obj)
def tpc_vote(self, transaction):
pass
More information about the Checkins
mailing list