[ZODB-Dev] Ape newbie

Adam Groszer adamg at mailbox.hu
Thu May 22 13:12:27 EDT 2003


Please help, I'm stuck

I brought together from the tests of Ape the attached script,
tried to change the MappingGateway to write the data to MySQL.
Currently the stack trace is:

Traceback (most recent call last):
  File "P:\PMSpy\test\apetest2.py", line 244, in ?
    x.testStoreAndLoad()
  File "P:\PMSpy\test\apetest2.py", line 200, in testStoreAndLoad
    get_transaction().commit()
  File "C:\Python22\lib\site-packages\ZODB\Transaction.py", line 272, in
commit
    ncommitted += self._commit_objects(objects)
  File "C:\Python22\lib\site-packages\ZODB\Transaction.py", line 388, in
_commit
_objects
    jar.commit(o, self)
  File "C:\Python22\lib\site-packages\apelib\zodb3\connection.py", line 281,
in
commit
    s=dbstore(oid,serial,p,version,transaction)
  File "C:\Python22\lib\site-packages\apelib\zodb3\storage.py", line 207, in
sto
re
    raise POSException.ConflictError(
ZODB.POSException.ConflictError: (10,) already exists

(((
My final goal would be to read/write the dummy class (object) to an SQL
table.
After that I'd like to map somehow the properties of a class to columns of a
table.
Eg:
dummy.value <-> table.value
dummy.code  <-> table.code
dummy.name  <-> table.name
and so on
)))

Adam
-------------- next part --------------
import ZODB
from Persistence import PersistentMapping
from cPickle import dumps, loads

from apelib.core.classifiers import FixedClassifier
from apelib.core.interfaces import ISerializer
from apelib.core.gateways import CompositeGateway, MappingGateway
from apelib.core.mapper import Mapper
from apelib.core.schemas import RowSequenceSchema
from apelib.core.serializers import CompositeSerializer, StringDataAttribute
from apelib.zodb3.serializers \
	 import FixedPersistentMapping, RollCall, RemainingState

from apelib.sql.dbapi import DBAPIConnector

from apelib.zodb3.db import ApeDB
from apelib.zodb3.storage import ApeStorage
from apelib.zodb3.resource import StaticResource
from apelib.zodb3.utils import copyOf

from apelib.sql.classification import SQLClassification
from apelib.sql.structure import SQLFolderItems
from apelib.sql.properties import SQLProperties
from apelib.sql.keygen import SQLKeychainGenerator

TESTKEY = 10
TEST2KEY = 11

class dummy(Persistent):
	value=0
	
	def setvalue(self,v):
		self.value = v
	
	def getvalue(self):
		return self.value

class SimpleItemsSerializer:

	__implements__ = ISerializer

	schema = RowSequenceSchema()
	schema.addField('name')
	schema.addField('pickle')

	def getSchema(self):
		return self.schema

	def serialize(self, object, event):
		res = []
		for k, v in object.items():
			res.append((k, dumps(v)))
			event.notifySerialized(k, v, 0)
		res.sort()
		event.ignoreAttribute('data')
		event.ignoreAttribute('_container')
		return res

	def deserialize(self, object, event, state):
		d = {}
		for k, v in state:
			o = loads(v)
			d[k] = o
			event.notifyDeserialized(k, o)
		object.__init__(d)


class SerialTestBase:

	def setUp(self):
		self.conns = {}
		
		classifier = FixedClassifier()
		classifier.register(TESTKEY, 'test_mapper')
		classifier.register(TEST2KEY, 'test_mapper_2')
		#a
		#classifier.setGateway(SQLClassification())

		ser2 = CompositeSerializer('Persistence', 'PersistentMapping')
		fixed_items_serializer = FixedPersistentMapping()
		fixed_items_serializer.add('TestRoot', (TESTKEY,), ('test_mapper',))
		fixed_items_serializer.add('TestRoot2', (TEST2KEY,), ('test_mapper_2',))
		ser2.addSerializer('fixed_items', fixed_items_serializer)
		ser2.addSerializer('roll_call', RollCall())

		root_mapper = Mapper(None, ser2, CompositeGateway(), classifier)
		self.root_mapper = root_mapper
		
		#a
		keychain_gen = SQLKeychainGenerator()
		root_mapper.setKeychainGenerator(keychain_gen)
		
		# Create "test_mapper", which allows a "strdata" attribute.

		ser1 = CompositeSerializer('Persistence', 'PersistentMapping')
		items_serializer = SimpleItemsSerializer()
		ser1.addSerializer('items', items_serializer)
		props_serializer = StringDataAttribute('strdata')
		ser1.addSerializer('properties', props_serializer)
		ser1.addSerializer('roll_call', RollCall())

		gw1 = CompositeGateway()
		#a
		items_gw = SQLFolderItems()
		#items_gw = MappingGateway(items_serializer.getSchema())
		self.items_gw = items_gw
		gw1.addGateway('items', items_gw)
		#a
		props_gw = SQLProperties()
		#props_gw = MappingGateway(props_serializer.getSchema())
		self.props_gw = props_gw
		gw1.addGateway('properties', props_gw)

		om1 = Mapper(root_mapper, ser1, gw1)
		self.om1 = om1
		root_mapper.addSubMapper('test_mapper', om1)
		
		for initializer in (
			items_gw,
			props_gw,
			keychain_gen):
			root_mapper.addInitializer(initializer)

		# Create "test_mapper_2", which stores a remainder.

		ser = CompositeSerializer('Persistence', 'PersistentMapping')
		items_serializer = SimpleItemsSerializer()
		ser.addSerializer('items', items_serializer)
		remainder_serializer = RemainingState()
		ser.addSerializer('remainder', remainder_serializer)

		gw = CompositeGateway()
		items_gw = MappingGateway(items_serializer.getSchema())
		gw.addGateway('items', items_gw)
		remainder_gw = MappingGateway(remainder_serializer.getSchema())
		gw.addGateway('remainder', remainder_gw)

		om = Mapper(root_mapper, ser, gw)
		root_mapper.addSubMapper('test_mapper_2', om)


	def tearDown(self):
		pass


class ApeStorageTests (SerialTestBase):
	# Tests of ApeStorage and ApeConnection.
	
	dbapi_module = None  # Name of the Database API module (required)
	dbapi_params = ()	# Positional args for connect()
	dbapi_kwparams = {}  # Keyword args for connect()
	
	def getConnector(self):
		return DBAPIConnector(self.dbapi_module, self.dbapi_params,
							  self.dbapi_kwparams, prefix='test_temp')

	def setUp(self):
		SerialTestBase.setUp(self)
		
		conn = self.getConnector()
		
		resource = StaticResource(self.root_mapper)
		self.conns = {'db': conn}
		storage = ApeStorage(resource, self.conns, clear_all=1)
		self.storage = storage
		db = ApeDB(storage, resource)
		self.db = db

	def clear(self):
		self.storage.initDatabases(clear_all=1)
		for conn in self.conns.values():
			conn.db.commit()

	def tearDown(self):
		get_transaction().abort()
		self.clear()
		self.db.close()
		SerialTestBase.tearDown(self)

	def testStoreAndLoad(self):
		ob = PersistentMapping()
		ob.strdata = '345'
		ob['a'] = 'b'
		ob['c'] = 'd'

		dummy = PersistentMapping()

		conn1 = self.db.open()
		conn2 = None
		conn3 = None
		try:

			# Load the root and create a new object
			root = conn1.root()
			get_transaction().begin()
			root['TestRoot'] = ob
			root['TestRoot2'] = dummy
			get_transaction().commit()
			ob1 = conn1.loadStub((TESTKEY,))
			#self.assertEqual(ob1.strdata, ob.strdata)
			#self.assertEqual(ob1.items(), ob.items())

			# Verify a new object was stored and make a change
			get_transaction().begin()
			conn2 = self.db.open()
			ob2 = conn2.loadStub((TESTKEY,))
			#self.assertEqual(ob2.strdata, ob.strdata)
			#self.assertEqual(ob2.items(), ob.items())
			ob2.strdata = '678'
			get_transaction().commit()

			# Verify the change was stored and make another change
			conn3 = self.db.open()
			ob3 = conn3.loadStub((TESTKEY,))
			#self.assertEqual(ob3.strdata, '678')
			#self.assertEqual(ob3.items(), ob.items())
			ob3.strdata = '901'
			get_transaction().commit()
			conn3.close()
			conn3 = None
			conn3 = self.db.open()
			ob3 = conn3.loadStub((TESTKEY,))
			#self.assertEqual(ob3.strdata, '901')

			# Verify we didn't accidentally change the original object
			#self.assertEqual(ob.strdata, '345')

		finally:
			conn1.close()
			if conn2 is not None:
				conn2.close()
			if conn3 is not None:
				conn3.close()


class MySQLTests (ApeStorageTests):
	dbapi_module = 'MySQLdb'
	dbapi_kwparams = {'host':'localhost', 'user':'adi', 'passwd':'r', 'db': 'ape'}

x = MySQLTests()
x.setUp()
x.testStoreAndLoad()
x.tearDown()


More information about the ZODB-Dev mailing list