Hi Michael
I made a simplified but I think for the ORM equivalent example which I attach.
In ExamplesTest.py I commented:
# essential: ORM canot cope if this comes after s._mother = m

It seems if that condition is not met then there is indefinite
recursion. Whether that could/should be avoided by the ORM I do not
know.

I just noticed a mistake. Need to add to ExamplesOrm.py:
mapper(OldSon, inherits=son_mapper, polymorphic_identity='oldson')
This did not change the test results.

Thanks for your time
Ernst

> Michael Bayer:
>Its impossible for me to assist you further without the benefit of a complete 
>example of what you're doing, including both tables, both >mappers, an example 
>of their manipulation.   If you attach a test case make sure its self 
>contained and does not rely on external >libraries other than SQLAlchemy.    
>There should not be recursion issues in SQLAlchemy but its possible that in 
>some cases they are >unavoidable, if things are configured to point to 
>themselves in some way (though I cannot picture how you'd be doing that 
>without >full details).

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

"""
doubly linked one to one reationship

"""
class Mother(object):
#==============
  def __init__(self, son):
    self._son = son
    self._givenName = ''

  def __str__(self): return self.__class__.__name__+'('+self._givenName+' has son '+self._son._givenName+')'


class Son(object):
#==============
  def __init__(self): 
    self._mother = None
    self._givenName = ''

  def __str__(self): return self.__class__.__name__+'('+self._givenName+' has mother '+self._mother._givenName+')'

class YoungSon(Son): pass
#==============

class OldSon(Son): pass
#==============
from Examples import *
from sqlalchemy import Table, Column, Integer, String, Boolean, Date, MetaData, Sequence, ForeignKey, create_engine
from sqlalchemy.orm import mapper, relation, backref

"""
One to one relationship mother and son (only ever one and only one son!)
In objects:
  aMother._son
  aSon._mother

"""
def mappings(metadata):
  mothers_table = Table('mothers', metadata,
    Column('id',Integer, primary_key=True),        # not in object
    Column('son', Integer, ForeignKey('sons.id')), # not in object

    Column('_givenName', String(40))
  )
  
  
  sons_table = Table('sons', metadata,
    Column('id',Integer, primary_key=True),      # not in object
    Column('type', String(30),nullable=False),   # not in object

    Column('_givenName', String(40))
  )
  
  mapper(Mother, mothers_table, properties={
    '_son':relation(Son, backref=backref('_mother', uselist=False))
  })
  

  son_mapper = mapper(Son, sons_table,  polymorphic_on=sons_table.c.type, polymorphic_identity='son')
  mapper(YoungSon, inherits=son_mapper ,        polymorphic_identity='youngson')

#!/usr/bin/python
# vim: set fileencoding=UTF-8 :

import os
import unittest
from  Examples import *
import ExamplesOrm

from sqlalchemy.orm import sessionmaker, clear_mappers
from sqlalchemy import create_engine, MetaData
import transaction

class ApplicationTest(unittest.TestCase):

  def setUp(self):
    """return db session object after creating the database schema according to ORM 

    """
 
    orm = ExamplesOrm 
    self.engine = create_engine('sqlite:///:memory:') #overwritting what TG2 may have!
    #self.engine = create_engine('sqlite:///%(here)s/devdata.db') #overwritting what TG2 may have!
    #print "setUp BEFORE os.path.exists('devdata.db')", os.path.exists('devdata.db')
    #self.engine = create_engine('sqlite:///devdata.db') #overwritting what TG2 may have!

    self.metadata = MetaData(self.engine)
    Session = sessionmaker()
    Session.configure(bind=self.engine)
    self.session = Session()
    orm.mappings(self.metadata)
    self.metadata.create_all(bind=self.engine)
    transaction.commit()
    #print "setUp AFTER  os.path.exists('devdata.db')", os.path.exists('devdata.db')
  
  def tearDown(self):
    #print "tearDown BEFORE os.path.exists('devdata.db')", os.path.exists('devdata.db')
    clear_mappers()
    self.metadata.drop_all(bind=self.engine)
    self.session.close()
    #print "tearDown AFTER  os.path.exists('devdata.db')", os.path.exists('devdata.db')

  def _alternateSession(self):
    Session = sessionmaker()
    Session.configure(bind=self.engine)
    return Session()

  def testCreateSchema(self):
    #would be nice to list tables and columns created

    #the table exists and has no row in it
    self.assertTrue(self.session.query(Mother).count() == 0)

  def testDoublyLinkedOneToOne(self):
    s = Son()
    s._givenName = 'Albert'
    m = Mother(s)
    m._givenName = 'Maria'
    s._mother = m
    print m, s

    #now add

    self.session.add(m)
    self.session.commit()
    self.assertTrue(self.session.query(Mother).count() == 1)
    print self.session.query(Mother).first()
    print self.session.query(Mother).first()._son

    s = self._alternateSession()
    print s.query(Mother).first()._son._mother
   
  def testExchangeSon(self):
    s = Son()
    s._givenName = 'Albert'
    m = Mother(s)
    m._givenName = 'Maria'
    s._mother = m
    print m, s

    #now exchange
    s = Son()
    s._givenName = 'Paul'
    s._mother = m
    m._son = s
    print m, s

  def testInheritance(self):
    s = YoungSon()
    s._givenName = 'YoungJim'
    m = Mother(s)
    m._givenName = 'Maria'
    s._mother = m
    print m, s

    s = OldSon()
    m._son = s     # essential: ORM canot cope if this comes after s._mother = m
    s._givenName = 'OldJohn'
    s._mother = m
    print m, s

if __name__ == '__main__':
  unittest.main()

Reply via email to