[Checkins] SVN: z3c.zalchemy/sandbox/src/z3c/ refactored to
z3c.zalchemy, added create to connect directive, TODO: fix tests
Bernd Dorn
bernd.dorn at fhv.at
Fri Apr 21 06:25:36 EDT 2006
Log message for revision 67202:
refactored to z3c.zalchemy, added create to connect directive, TODO: fix tests
Changed:
A z3c.zalchemy/sandbox/src/z3c/__init__.py
U z3c.zalchemy/sandbox/src/z3c/zalchemy/README.txt
U z3c.zalchemy/sandbox/src/z3c/zalchemy/datamanager.py
U z3c.zalchemy/sandbox/src/z3c/zalchemy/metaconfigure.py
U z3c.zalchemy/sandbox/src/z3c/zalchemy/metadirectives.py
U z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/TRANSACTION.txt
U z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_directives.py
U z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_zalchemy.py
A z3c.zalchemy/sandbox/src/z3c/zalchemy/z3c.zalchemy-configure.zcml
A z3c.zalchemy/sandbox/src/z3c/zalchemy/z3c.zalchemy-meta.zcml
D z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-configure.zcml
D z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-meta.zcml
-=-
Added: z3c.zalchemy/sandbox/src/z3c/__init__.py
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/__init__.py 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/__init__.py 2006-04-21 10:25:35 UTC (rev 67202)
@@ -0,0 +1,19 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Corporation 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.
+#
+##############################################################################
+"""z3c.zalchemy integrates sqlalchemy into zope 3
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
Property changes on: z3c.zalchemy/sandbox/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/README.txt
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/README.txt 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/README.txt 2006-04-21 10:25:35 UTC (rev 67202)
@@ -2,8 +2,8 @@
SQLAlchemy and Zope 3
=====================
-"zalchemy" integrates the object relational mapper sqlalchemy into zope 3
-as SQLOS integrates sqlobject.
+"z3c.zalchemy" integrates the object relational mapper sqlalchemy into
+zope 3 as SQLOS integrates sqlobject.
zalchemy tries to do it's best not to interfere with the standard sqlalchemy
usage.
@@ -23,26 +23,29 @@
A SQLAlchemy engine is represented as a utility :
>>> import os
- >>> from zalchemy.datamanager import AlchemyEngineUtility
+ >>> from z3c.zalchemy.datamanager import AlchemyEngineUtility
>>> engineUtil = AlchemyEngineUtility(
... 'sqlite',
... dns='sqlite://',
... )
-We create our tables as usual sqlalchemy table :
-Note that we use a ProxyEngine which is important here.
-The real connection to database engine will be done later in our utility.
+We create our tables as usual sqlalchemy table :
>>> import sqlalchemy
- >>> engine = sqlalchemy.ext.proxy.ProxyEngine()
>>> aTable = sqlalchemy.Table(
... 'aTable',
- ... engine,
... sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
... sqlalchemy.Column('value', sqlalchemy.Integer),
... )
+Note that by not specifying an engine we use a ProxyEngine which is
+important here. The real connection to database engine will be done
+later in our utility.
+
+ >>> aTable.engine
+ <sqlalchemy.ext.proxy.ProxyEngine object at ...>
+
Define a simple class which will be used later to map to a database table.
>>> class A(object):
@@ -52,10 +55,11 @@
>>> sqlalchemy.assign_mapper(A, aTable)
-The next step is to connect the table to the database engine.
-We use our utility for that :
+The next step is to connect the table to the database engine. We use
+our utility for that. The ``create`` argument tells the utility if it
+should try to create the table.
- >>> engineUtil.addTable(aTable)
+ >>> engineUtil.addTable(aTable,create=True)
To let zalchemy do his magic thing we need to register our database utility
as a named utility :
@@ -66,26 +70,9 @@
From now on zalchemy takes care of the zope transaction process behind the
scenes :
- connect the engine to the tables for every thread
-- create the tables in the database if not already done
- handle the two phase commit process
- disconnect the engine from the tables at the end of the thread
-Now let's try to use our database objects :
-
- >>> a = A()
- >>> a.value = 1
- >>> sqlalchemy.objectstore.commit()
- Traceback (most recent call last):
- ...
- AttributeError: No connection established
-
-Ups, this is because the tabel is not connected to a real database engine.
-We need to use zope transactions.
-
-First let's clear the current unit of work :
-
- >>> sqlalchemy.objectstore.clear()
-
Note that the transaction handling is done inside zope.
>>> import transaction
@@ -93,7 +80,7 @@
Then we need to simulate a beforeTraversal Event :
- >>> from zalchemy.datamanager import beforeTraversal
+ >>> from z3c.zalchemy.datamanager import beforeTraversal
>>> beforeTraversal(None)
>>> a = A()
@@ -106,6 +93,8 @@
>>> txn = transaction.begin()
>>> beforeTraversal(None)
+XXX this is not the same db, use filebased db?
+
>>> a = A.get(1)
>>> a.value
123
@@ -126,14 +115,13 @@
>>> bTable = sqlalchemy.Table(
... 'bTable',
- ... engine,
... sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
... sqlalchemy.Column('value', sqlalchemy.String),
... )
>>> class B(object):
... pass
>>> sqlalchemy.assign_mapper(B, bTable)
- >>> engine2Util.addTable(bTable)
+ >>> engine2Util.addTable(bTable,create=True)
>>> txn = transaction.begin()
>>> beforeTraversal(None)
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/datamanager.py
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/datamanager.py 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/datamanager.py 2006-04-21 10:25:35 UTC (rev 67202)
@@ -41,7 +41,7 @@
self.storage = local()
self.createdTables = {}
- def addTable(self, table):
+ def addTable(self, table, create=False):
if not isinstance(table.engine, sqlalchemy.ext.proxy.ProxyEngine):
raise TypeError(table.engine)
utils = getUtilitiesFor(IAlchemyEngineUtility)
@@ -50,15 +50,34 @@
#TODO: should raise an exception here
return
self.tables.append(table)
+ if create:
+ self.createTable(table)
- def connectTablesForThread(self):
- # create a thread local engine
+ def createTable(self,table):
+
+ """tries to create the given table if not there"""
+ self.initEngine()
+ table.engine.engine = self.storage.engine
+ table.create()
+
+
+ def initEngine(self):
+
+ """create a thread local engine if not there, returns True if
+ a new engine is created"""
+
engine=getattr(self.storage,'engine',None)
if engine is not None:
- return
+ return False
self.storage.engine = create_engine(self.dns,
self.kw,
echo=self.echo)
+ return True
+
+ def connectTablesForThread(self):
+ # create a thread local engine
+ if not self.initEngine():
+ return
engine = self.storage.engine
# create a data manager
if self.echo:
@@ -69,14 +88,6 @@
# connect the tables to the engine
for table in self.tables:
table.engine.engine = engine
- #TODO: this is a bad hack which must go away soon !
- if table not in self.createdTables:
- try:
- # make sure the table exists :
- table.create()
- except:
- pass
- self.createdTables[table]=True
def dataManagerFinished(self):
self.storage.engine=None
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/metaconfigure.py
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/metaconfigure.py 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/metaconfigure.py 2006-04-21 10:25:35 UTC (rev 67202)
@@ -25,15 +25,15 @@
permission=PublicPermission,
name=name)
-def connect(_context, engine, table):
+def connect(_context, engine, table, create=False):
_context.action(
discriminator = (engine, table),
callable = connector,
- args = (engine, table)
+ args = (engine, table, create)
)
-def connector(engine, table):
+def connector(engine, table, create):
util = component.getUtility(IAlchemyEngineUtility, engine)
- util.addTable(table)
+ util.addTable(table,create=create)
#connections.append((util, table))
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/metadirectives.py
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/metadirectives.py 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/metadirectives.py 2006-04-21 10:25:35 UTC (rev 67202)
@@ -13,7 +13,7 @@
##############################################################################
from zope import interface
from zope import schema
-from zope.configuration.fields import GlobalObject
+from zope.configuration.fields import GlobalObject,Bool
class IEngineDirective(interface.Interface):
@@ -52,3 +52,5 @@
required = True,
)
+ create = Bool(title=u'Create Table',default=False,
+ required=False)
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/TRANSACTION.txt
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/TRANSACTION.txt 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/TRANSACTION.txt 2006-04-21 10:25:35 UTC (rev 67202)
@@ -2,7 +2,7 @@
================================
When a zope transaction is used also a sqlalchemy transaction must be
-activated. "zalchemy" installs a data manager every time a new zope
+activated. "z3c.zalchemy" installs a data manager every time a new zope
transaction is created.
Setup zope's test environment :
@@ -13,9 +13,9 @@
Create a utility to provide a database :
>>> from zope.component import provideUtility
- >>> from zalchemy.datamanager import AlchemyEngineUtility
+ >>> from z3c.zalchemy.datamanager import AlchemyEngineUtility
>>> engineUtility = AlchemyEngineUtility('database',
- ... 'sqlite://filename=abc.db',
+ ... 'sqlite://filename=/tmp/abc.db',
... echo=False)
>>> provideUtility(engineUtility, name="test")
@@ -40,7 +40,7 @@
>>> import os
>>> try:
- ... os.remove('abc.db')
+ ... os.remove('/tmp/abc.db')
... except:
... pass
@@ -57,7 +57,7 @@
Now we need to connect our table to a real engine :
- >>> from zalchemy.datamanager import beforeTraversal
+ >>> from z3c.zalchemy.datamanager import beforeTraversal
>>> beforeTraversal(None)
>>> aTable.engine.engine is not None
@@ -143,8 +143,16 @@
Connect the new table to the already existing database :
- >>> engineUtility.addTable(bTable)
+ >>> engineUtility.addTable(bTable,create=True)
+ >>> not not bTable.engine.engine
+ True
+The table should now be created.
+
+ >>> c = bTable.engine.engine.execute("select * from bTable")
+ >>> [row for row in c]
+ []
+
>>> log = []
>>> def createB():
... txn = transaction.begin()
@@ -169,6 +177,10 @@
>>> log
[1]
+XXX why do we have to do this?
+
+ >>> transaction.get().commit()
+
>>> log = []
>>> thread = threading.Thread(target=doB)
>>> thread.start()
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_directives.py
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_directives.py 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_directives.py 2006-04-21 10:25:35 UTC (rev 67202)
@@ -7,8 +7,8 @@
from zope.testing.doctestunit import DocTestSuite
from zope.app.testing.placelesssetup import PlacelessSetup
-import zalchemy
-from zalchemy.interfaces import IAlchemyEngineUtility
+import z3c.zalchemy
+from z3c.zalchemy.interfaces import IAlchemyEngineUtility
template = """<configure
xmlns='http://namespaces.zope.org/zope'
@@ -22,7 +22,7 @@
def setUp(self):
super(TestDirectives, self).setUp()
- XMLConfig('meta.zcml', zalchemy)()
+ XMLConfig('meta.zcml', z3c.zalchemy)()
def testEngineDirective(self):
xmlconfig(StringIO(template % (
@@ -53,14 +53,14 @@
/>
<alchemy:connect
engine="sqlite-in-memory"
- table="zalchemy.tests.environ.testTable"
+ table="z3c.zalchemy.tests.environ.testTable"
/>
'''
)))
util = component.getUtility(IAlchemyEngineUtility,'sqlite-in-memory')
self.assert_(len(util.tables)==1)
self.assertEqual(util.tables[0],
- zalchemy.tests.environ.testTable)
+ z3c.zalchemy.tests.environ.testTable)
def tearDown(self):
PlacelessSetup.tearDown(self)
Modified: z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_zalchemy.py
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_zalchemy.py 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/tests/test_zalchemy.py 2006-04-21 10:25:35 UTC (rev 67202)
@@ -1,11 +1,28 @@
import unittest
+import doctest
from zope.testing.doctestunit import DocFileSuite
+from zope.app.testing import setup
+def setUp(test):
+ setup.placefulSetUp()
+
+
+def tearDown(test):
+ setup.placefulTearDown()
+
+
+
def test_suite():
return unittest.TestSuite((
- DocFileSuite('TRANSACTION.txt'),
- DocFileSuite('../README.txt'),
- ))
+ DocFileSuite('../README.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ DocFileSuite('TRANSACTION.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
Copied: z3c.zalchemy/sandbox/src/z3c/zalchemy/z3c.zalchemy-configure.zcml (from rev 67198, z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-configure.zcml)
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-configure.zcml 2006-04-21 08:24:00 UTC (rev 67198)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/z3c.zalchemy-configure.zcml 2006-04-21 10:25:35 UTC (rev 67202)
@@ -0,0 +1 @@
+<include package="z3c.zalchemy"/>
Copied: z3c.zalchemy/sandbox/src/z3c/zalchemy/z3c.zalchemy-meta.zcml (from rev 67198, z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-meta.zcml)
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-meta.zcml 2006-04-21 08:24:00 UTC (rev 67198)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/z3c.zalchemy-meta.zcml 2006-04-21 10:25:35 UTC (rev 67202)
@@ -0,0 +1 @@
+<include package="z3c.zalchemy" file="meta.zcml" />
Deleted: z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-configure.zcml
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-configure.zcml 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-configure.zcml 2006-04-21 10:25:35 UTC (rev 67202)
@@ -1 +0,0 @@
-<include package="zalchemy"/>
Deleted: z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-meta.zcml
===================================================================
--- z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-meta.zcml 2006-04-21 09:59:20 UTC (rev 67201)
+++ z3c.zalchemy/sandbox/src/z3c/zalchemy/zalchemy-meta.zcml 2006-04-21 10:25:35 UTC (rev 67202)
@@ -1 +0,0 @@
-<include package="zalchemy" file="meta.zcml" />
More information about the Checkins
mailing list