in short, SA is about people *doing things with their databases right
now* as opposed to rambling and handwaving about how ORMs should and
should not work.

This is why i am here.

there is far too much in that post to respond to, ...

i agree my post is far too much and definitely badly presented,
sorry about that.

okay, one piece at a time.

here the case where B inherits A, and A references either A or B. i
cannot get this to work.

http://linuxteam.sistechnology.com/o2rm/sa_B_inh_A_A_ref_AB.py
-------
#$Id$

from sqlalchemy import *

_debug = 0*'call'
ECHO = 0

def mmapper( *args,**kargs):
   func = mapper
   if 'call' in _debug:
       print func,'(\n ', args, '\n  '+ '\n  '.join( '%s=%s' % kv for
kv in kargs.iteritems()), '\n)'
   return func( *args, **kargs)


class Base( object):
   def __str__( self):
       r = self.__class__.__name__ + '('
       for k in self.props:
           v = getattr( self, k, '<notset>')
           if isinstance( v, Base):
               v = '>'+v.data
           r+= ' '+k+'='+str(v)
       return r+' )'



def case( clear =False, Alink='B', ):
   #concrete=False, Blink=''
   #inh=True, polymorphic=True,

   class A( Base):
       props = [ 'id', 'data1', 'link1', ]
       data = property( lambda me: me.data1)
       pass
   class B( A ):
       props = A.props + [ 'data2', ]
       data = property( lambda me: me.data2)
       pass

   db = create_engine( 'sqlite:///:memory:')
   meta = BoundMetaData( db)
   meta.engine.echo = ECHO

   class tables: pass

   tables.A = Table('A', meta,
           Column('id', Integer, primary_key=True),
           Column('data1', String, ),
           Column('atype', String),
       )
   if Alink:
       tables.A.append_column( Column('link1_id', Integer,
                       ForeignKey( Alink+'.id',
                          use_alter=True, name='zt1id_fk'
                       )
               )
       )


   tables.B = Table('B', meta,
           Column('data2', String, ),
           Column('id', Integer,
                       ForeignKey( 'A.id'),
                       primary_key=True,
               ),
   )
   meta.create_all()


   class mappers: pass

   ajoin = {
       'A': tables.A.select( tables.A.c.atype == 'A'),
       'B': join( tables.A, tables.B, tables.B.c.id ==tables.A.c.id),
   }
   Ajoin = polymorphic_union( ajoin, None )
   mappers.A = mmapper( A, tables.A,
       select_table=Ajoin, polymorphic_on=Ajoin.c.atype,
       polymorphic_identity='A'
   )

   if Alink:
       mappers.A.add_property( 'link1',
               relation( Alink == 'A' and A or B,
                   primaryjoin= tables.A.c.link1_id==(Alink=='A' and
tables.A or tables.B).c.id,
                   lazy=True,
                   uselist=False,
                   post_update=True
               )
       )

   mappers.B = mmapper( B, tables.B,
           polymorphic_identity='B',
           inherits = mappers.A,
           inherit_condition = (tables.A.c.id == tables.B.c.id),
   )


   #populate
   session = create_session()

   a = A()
   a.data1 = 'aa'
   b = B()
   if 'data1' in B.props:
       b.data1 = 'ba'
   b.data2 = 'bb'

   if Alink:
       a.link1 = (Alink == 'A' and a or b)

   session.save(a)
   session.save(b)

   session.flush()

   print a      #does not work after session.clear() #XXX
session-clear?
   print b      #does not work after session.clear() #XXX
session-clear?
   expected = [
       dict( klas=A, id=a.id, str= str(a)),
       dict( klas=B, id=b.id, str= str(b)),
   ]

   if clear: session.clear()

   print list( tables.A.select().execute() )
   print list( tables.B.select().execute() )

   test( session, expected )


def test( session, items):
   for single in [1,0]:
       for item in items:
           klas = item['klas']
           aid  = item['id']
           astr = item['str']
           if single:
               s = session.query( klas).get_by_id( aid)
               x = str(s)
               r = 'assert single %(x)s ; expect: %(astr)s' % locals()
               print '>>>>>', r
               assert x == astr, r
           else:
               s = session.query( klas).select()
               x = '; '.join( str(z) for z in s )
               r = 'assert multiple %(x)s ; expect: %(astr)s' %
locals()
               assert len(s) >= 1, 'size? '+ r
               assert str(s[0]) == astr, r


import sys
kargs = dict( kv.split('=') for kv in sys.argv[1:])
case( **kargs)

# vim:ts=4:sw=4:expandtab
-------

$ python sa_B_inh_A_A_ref_AB.py Alink=A
....
sqlalchemy.exceptions.SQLError: (OperationalError) no such column: A.id
.....

$ python sa_B_inh_A_A_ref_AB.py Alink=B
...
sqlalchemy.exceptions.InvalidRequestError: Column 'B.id' is not
available, due to conflicting property
'id':<sqlalchemy.orm.properties.ColumnProperty object at 0xb79343ec>


As of rewriting SA -no! i don't want such thing, i just want to be able
to do my (little) part. In this case it is more about hiding SA-details
than some great new invention.


======
P.S. u can remove the other repeating post from another account fo mine
- seems GG has weird latenicies, hence i double posted... and first one
appeared 10hrs later than second.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to