[Checkins] SVN: z3c.zalchemy/trunk/src/z3c/zalchemy/ Simple
container implementation which contains all objects of a
given SQLAlchemy class
Jürgen Kartnaller
juergen at kartnaller.at
Thu Jun 29 04:45:56 EDT 2006
Log message for revision 68902:
Simple container implementation which contains all objects of a given SQLAlchemy class
Changed:
U z3c.zalchemy/trunk/src/z3c/zalchemy/container.py
A z3c.zalchemy/trunk/src/z3c/zalchemy/container.txt
A z3c.zalchemy/trunk/src/z3c/zalchemy/tests/test_container.py
-=-
Modified: z3c.zalchemy/trunk/src/z3c/zalchemy/container.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/container.py 2006-06-28 23:22:15 UTC (rev 68901)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/container.py 2006-06-29 08:45:54 UTC (rev 68902)
@@ -62,7 +62,6 @@
class SQLAlchemyNameChooser(NameChooser):
def checkName(self, name, container):
-
if isinstance(name, str):
name = unicode(name)
elif not isinstance(name, unicode):
@@ -70,23 +69,15 @@
unproxied = removeSecurityProxy(container)
if not name.startswith(unproxied._class.__name__+'.'):
- raise UserError(
- _("Invalid name for SQLAlchemy object")
- )
- try:
- id = int(name.split('.')[-1])
- except:
- raise UserError(
- _("Invalid id for SQLAlchemy object")
- )
-
+ raise UserError("Invalid name for SQLAlchemy object")
return True
def chooseName(self, name, obj):
- # commit the object to make sure it contains an id
+ # flush the object to make sure it contains an id
session = z3c.zalchemy.getSession()
- session.flush(obj)
- return '%s.%i'%(obj.__class__.__name__, obj.id)
+ session.save(obj)
+ session.flush([obj])
+ return self.context._toStringIdentifier(obj)
class SQLAlchemyContainer(Persistent, Contained):
@@ -115,19 +106,16 @@
return iter(self.keys())
def items(self):
- for obj in self._class.mapper.select():
- name = '%s.%i'%(self._class.__name__, obj.id)
+ session = z3c.zalchemy.getSession()
+ query = session.query(self._class)
+ for obj in query.select():
+ name = self._toStringIdentifier(obj)
yield (name, contained(obj, self, name) )
def __getitem__(self, name):
if not isinstance(name, basestring):
raise KeyError, "%s is not a string" % name
- vals = name.split('.')
- try:
- id=int(vals[-1])
- except ValueError:
- return None
- obj = self._class.mapper.selectfirst(self._class.c.id==id)
+ obj = self._fromStringIdentifier(name)
if obj is None:
raise KeyError, name
return contained(obj, self, name)
@@ -144,7 +132,7 @@
def __len__(self):
try:
session = z3c.zalchemy.getSession()
- query = session.query(class_)
+ query = session.query(self._class)
return query.count()
except sqlalchemy.exceptions.SQLError:
# we don't want an exception in case of database problems
@@ -158,5 +146,21 @@
def __setitem__(self, name, item):
session = z3c.zalchemy.getSession()
- session.flush(item)
+ session.save(item)
+ session.flush([item])
+ def _toStringIdentifier(self, obj):
+ session = z3c.zalchemy.getSession()
+ mapper = session.mapper(obj.__class__)
+ instance_key = mapper.instance_key(obj)
+ ident = str(instance_key[1])
+ return '%s.%s'%(instance_key[0].__name__, ident)
+
+ def _fromStringIdentifier(self, name):
+ dotpos = name.find('.')
+ if dotpos<0:
+ return None
+ exec 'keys='+name[dotpos+1:]
+ session = z3c.zalchemy.getSession()
+ return session.query(self._class).get([str(key) for key in keys])
+
Added: z3c.zalchemy/trunk/src/z3c/zalchemy/container.txt
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/container.txt 2006-06-28 23:22:15 UTC (rev 68901)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/container.txt 2006-06-29 08:45:54 UTC (rev 68902)
@@ -0,0 +1,114 @@
+zalchemy container
+==================
+
+ >>> import z3c.zalchemy
+ >>> from z3c.zalchemy.tests.test_container import SQLTestSingle, SQLTestMulti
+ >>> from z3c.zalchemy.container import SQLAlchemyContainer
+
+ >>> session = z3c.zalchemy.getSession
+
+We create a container :
+
+ >>> c = SQLAlchemyContainer()
+
+And assign a class to the container.
+The class must be mapped to a table.
+
+ >>> c.className = 'z3c.zalchemy.tests.test_container.SQLTestSingle'
+
+
+WriteContainer
+--------------
+
+It is important to note that the name used to assign an item to a container
+is not used. The container is only saving the item in the session and then
+flushing it to the database.
+
+ >>> c[''] = SQLTestSingle()
+
+The above line has the same effect than this :
+
+ >>> t = SQLTestSingle()
+ >>> session().save(t)
+ >>> session().flush([t])
+
+Clean up for the next test :
+
+ >>> import transaction
+ >>> transaction.abort()
+
+ReadContainer
+-------------
+
+We can ask for the length :
+
+ >>> len(c)
+ 0
+
+ >>> session().save(SQLTestSingle())
+ >>> session().flush()
+
+We can iterate over the keys :
+
+ >>> [key for key in c.keys()]
+ ['SQLTestSingle.(1,)']
+
+We can iterate over the items :
+
+ >>> [item.id for key, item in c.items()]
+ [1]
+
+We can iterate over the values :
+
+ >>> [item.id for item in c.values()]
+ [1]
+
+ >>> session().save(SQLTestSingle())
+ >>> session().flush()
+ >>> len(c)
+ 2
+ >>> [key for key in c.keys()]
+ ['SQLTestSingle.(1,)', 'SQLTestSingle.(2,)']
+
+We can access specific object by key :
+
+ >>> c['SQLTestSingle.(1,)'].id
+ 1
+ >>> c['SQLTestSingle.(2,)'].id
+ 2
+
+Using compound primary keys
+---------------------------
+
+ >>> c = SQLAlchemyContainer()
+ >>> c.className = 'z3c.zalchemy.tests.test_container.SQLTestMulti'
+
+ >>> len(c)
+ 0
+
+ >>> session().save(SQLTestMulti(1, 'a'))
+ >>> session().flush()
+ >>> len(c)
+ 1
+ >>> [key for key in c.keys()]
+ ["SQLTestMulti.(1, 'a')"]
+ >>> c["SQLTestMulti.(1, 'a')"].id2
+ 'a'
+
+NameChooser
+===========
+
+ >>> from z3c.zalchemy.container import SQLAlchemyNameChooser
+ >>> nc = SQLAlchemyNameChooser(c)
+
+ >>> nc.checkName("SQLTestMulti.(1, 'b')", c)
+ True
+ >>> nc.checkName("SQLTestSingle.(1, 'a')", c)
+ Traceback (most recent call last):
+ ...
+ UserError: Invalid name for SQLAlchemy object
+
+ >>> t = SQLTestMulti(1, 'b')
+ >>> nc.chooseName('unused', t)
+ "SQLTestMulti.(1, 'b')"
+
Property changes on: z3c.zalchemy/trunk/src/z3c/zalchemy/container.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.zalchemy/trunk/src/z3c/zalchemy/tests/test_container.py
===================================================================
--- z3c.zalchemy/trunk/src/z3c/zalchemy/tests/test_container.py 2006-06-28 23:22:15 UTC (rev 68901)
+++ z3c.zalchemy/trunk/src/z3c/zalchemy/tests/test_container.py 2006-06-29 08:45:54 UTC (rev 68902)
@@ -0,0 +1,74 @@
+##############################################################################
+#
+# Copyright (c) 2006 ROBOTECH Logistiksysteme GmbH and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+import doctest
+from zope.app.testing import setup
+from zope.testing.doctestunit import DocFileSuite
+from zope.app.testing.placelesssetup import PlacelessSetup
+
+import sqlalchemy
+import z3c.zalchemy
+
+
+singlePrimaryKeyTable = sqlalchemy.Table(
+ 'singlePrimaryKeyTable',
+ z3c.zalchemy.metadata,
+ sqlalchemy.Column('id', sqlalchemy.Integer, primary_key = True),
+ sqlalchemy.Column('x', sqlalchemy.Integer),
+ )
+
+class SQLTestSingle(object):
+ pass
+
+sqlalchemy.mapper(SQLTestSingle, singlePrimaryKeyTable)
+
+
+multiPrimaryKeyTable = sqlalchemy.Table(
+ 'multiPrimaryKeyTable',
+ z3c.zalchemy.metadata,
+ sqlalchemy.Column('id1', sqlalchemy.Integer, primary_key = True),
+ sqlalchemy.Column('id2', sqlalchemy.String, primary_key = True),
+ sqlalchemy.Column('x', sqlalchemy.Integer),
+ )
+
+class SQLTestMulti(object):
+ def __init__(self, id1, id2):
+ self.id1 = id1
+ self.id2 = id2
+
+sqlalchemy.mapper(SQLTestMulti, multiPrimaryKeyTable)
+
+
+def setUp(test):
+ setup.placefulSetUp()
+ z3c.zalchemy.testing.placefulSetUp(test)
+ z3c.zalchemy.createTable('singlePrimaryKeyTable')
+ z3c.zalchemy.createTable('multiPrimaryKeyTable')
+
+def tearDown(test):
+ z3c.zalchemy.testing.placefulTearDown(test)
+ setup.placefulTearDown()
+
+
+def test_suite():
+ return unittest.TestSuite((
+ DocFileSuite('../container.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Property changes on: z3c.zalchemy/trunk/src/z3c/zalchemy/tests/test_container.py
___________________________________________________________________
Name: svn:eol-style
+ native
More information about the Checkins
mailing list