[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-12 Thread MikeCo

Must have been a bug in the default constructor prior to 0.5.0 final.
I got the same error rerunning with earlier version. Strange, I don't
remember now how I had this running before. Maybe with my own
constructor, but not worth igging to find out, it works with final
release.

On Jan 11, 1:43 pm, Darren Govoni dar...@ontrenet.com wrote:
 Ahhh, looks like I'm on rc4. Let me try final and see.

 On Sun, 2009-01-11 at 13:10 -0500, Michael Bayer wrote:
  0.5.0 final ?

  On Jan 11, 2009, at 12:21 PM, Darren Govoni wrote:

   Hi MikeCo,
    I tried your example, and got this error from SA 0.5.

   ValueError: need more than 0 values to unpack

   Darren

   On Fri, 2009-01-09 at 20:33 -0800, MikeCo wrote:
   from sqlalchemy import *
   from sqlalchemy.orm import *
   from sqlalchemy.ext.declarative import declarative_base

   dbname = ''
   dburl = 'sqlite:///%s' % dbname

   # set up environment
   eng = create_engine(dburl, echo=False)
   meta = MetaData(bind=eng)
   Base = declarative_base(metadata=meta)
   Session = sessionmaker()

   # D  self referential
   class D(Base):
      __tablename__ = 'D'
      id = Column(Integer, primary_key=True)
      id_d = Column(Integer, ForeignKey('D.id'))
      name = Column(Text)
      child = relation('D',
          backref=backref('parent', remote_side='D.id'))
      def __repr__(self):
          return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
   self.name)

   def initdb():
      print '# create the database'
      meta.drop_all(checkfirst=True)
      meta.create_all()
      sess = Session()

      # insert some data for self-reference relationship
      for ddata in ('d-one', 'd-two'):
          dobj = D(name=ddata)
          sess.add(dobj)
          dobj2 = D(name=ddata+'-child1')
          dobj.child.append(dobj2)
          dobj2 = D(name=ddata+'-child2')
          dobj.child.append(dobj2)
          dobj3 = D(name=ddata+'-child2'+'-child3')
          dobj2.child.append(dobj3)
      sess.commit()
      sess.close()

   def printobj(obj, indent=''):
      # recursive list
      print '%s%s' % (indent, obj)
      if hasattr(obj, 'child'):
          for ch in obj.child:
              printobj(ch, indent=indent+'    ')

   def listd():
      # retrieve and list
      sess = Session()
      print '# D-D'
      query = sess.query(D).filter(D.id_d==None).order_by(D.name)
      for dobj in query:
          printobj(dobj)
      sess.close()

   def tst3():
      # do stuff with self referential class D
      sess = Session()
      print #switch parentage of name 'd-two-child1' to 'd-one'
      print '# before'
      listd()
      child = sess.query(D).filter(D.name=='d-two-child1').one()
      parent = sess.query(D).filter(D.name=='d-one').one()
      eng.echo=True
      child.parent = parent
      child.name += ' MOVED'
      sess.commit()
      eng.echo=False
      print '# after'
      listd()

   initdb()
   tst3()
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-12 Thread Michael Bayer

yes, it was a bug that declarative wasn't translating the backref()  
arguments from strings.

On Jan 12, 2009, at 10:22 AM, MikeCo wrote:


 Must have been a bug in the default constructor prior to 0.5.0 final.
 I got the same error rerunning with earlier version. Strange, I don't
 remember now how I had this running before. Maybe with my own
 constructor, but not worth igging to find out, it works with final
 release.

 On Jan 11, 1:43 pm, Darren Govoni dar...@ontrenet.com wrote:
 Ahhh, looks like I'm on rc4. Let me try final and see.

 On Sun, 2009-01-11 at 13:10 -0500, Michael Bayer wrote:
 0.5.0 final ?

 On Jan 11, 2009, at 12:21 PM, Darren Govoni wrote:

 Hi MikeCo,
  I tried your example, and got this error from SA 0.5.

 ValueError: need more than 0 values to unpack

 Darren

 On Fri, 2009-01-09 at 20:33 -0800, MikeCo wrote:
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 dbname = ''
 dburl = 'sqlite:///%s' % dbname

 # set up environment
 eng = create_engine(dburl, echo=False)
 meta = MetaData(bind=eng)
 Base = declarative_base(metadata=meta)
 Session = sessionmaker()

 # D  self referential
 class D(Base):
__tablename__ = 'D'
id = Column(Integer, primary_key=True)
id_d = Column(Integer, ForeignKey('D.id'))
name = Column(Text)
child = relation('D',
backref=backref('parent', remote_side='D.id'))
def __repr__(self):
return '--D (id:%s-id_d:%s) %s --' % (self.id,  
 self.id_d,
 self.name)

 def initdb():
print '# create the database'
meta.drop_all(checkfirst=True)
meta.create_all()
sess = Session()

# insert some data for self-reference relationship
for ddata in ('d-one', 'd-two'):
dobj = D(name=ddata)
sess.add(dobj)
dobj2 = D(name=ddata+'-child1')
dobj.child.append(dobj2)
dobj2 = D(name=ddata+'-child2')
dobj.child.append(dobj2)
dobj3 = D(name=ddata+'-child2'+'-child3')
dobj2.child.append(dobj3)
sess.commit()
sess.close()

 def printobj(obj, indent=''):
# recursive list
print '%s%s' % (indent, obj)
if hasattr(obj, 'child'):
for ch in obj.child:
printobj(ch, indent=indent+'')

 def listd():
# retrieve and list
sess = Session()
print '# D-D'
query = sess.query(D).filter(D.id_d==None).order_by(D.name)
for dobj in query:
printobj(dobj)
sess.close()

 def tst3():
# do stuff with self referential class D
sess = Session()
print #switch parentage of name 'd-two-child1' to 'd-one'
print '# before'
listd()
child = sess.query(D).filter(D.name=='d-two-child1').one()
parent = sess.query(D).filter(D.name=='d-one').one()
eng.echo=True
child.parent = parent
child.name += ' MOVED'
sess.commit()
eng.echo=False
print '# after'
listd()

 initdb()
 tst3()
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-11 Thread Darren Govoni

Hi MikeCo,
  I tried your example, and got this error from SA 0.5.

ValueError: need more than 0 values to unpack

Darren

On Fri, 2009-01-09 at 20:33 -0800, MikeCo wrote:
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base
 
 dbname = ''
 dburl = 'sqlite:///%s' % dbname
 
 # set up environment
 eng = create_engine(dburl, echo=False)
 meta = MetaData(bind=eng)
 Base = declarative_base(metadata=meta)
 Session = sessionmaker()
 
 # D  self referential
 class D(Base):
 __tablename__ = 'D'
 id = Column(Integer, primary_key=True)
 id_d = Column(Integer, ForeignKey('D.id'))
 name = Column(Text)
 child = relation('D',
 backref=backref('parent', remote_side='D.id'))
 def __repr__(self):
 return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
 self.name)
 
 
 def initdb():
 print '# create the database'
 meta.drop_all(checkfirst=True)
 meta.create_all()
 sess = Session()
 
 # insert some data for self-reference relationship
 for ddata in ('d-one', 'd-two'):
 dobj = D(name=ddata)
 sess.add(dobj)
 dobj2 = D(name=ddata+'-child1')
 dobj.child.append(dobj2)
 dobj2 = D(name=ddata+'-child2')
 dobj.child.append(dobj2)
 dobj3 = D(name=ddata+'-child2'+'-child3')
 dobj2.child.append(dobj3)
 sess.commit()
 sess.close()
 
 def printobj(obj, indent=''):
 # recursive list
 print '%s%s' % (indent, obj)
 if hasattr(obj, 'child'):
 for ch in obj.child:
 printobj(ch, indent=indent+'')
 
 def listd():
 # retrieve and list
 sess = Session()
 print '# D-D'
 query = sess.query(D).filter(D.id_d==None).order_by(D.name)
 for dobj in query:
 printobj(dobj)
 sess.close()
 
 def tst3():
 # do stuff with self referential class D
 sess = Session()
 print #switch parentage of name 'd-two-child1' to 'd-one'
 print '# before'
 listd()
 child = sess.query(D).filter(D.name=='d-two-child1').one()
 parent = sess.query(D).filter(D.name=='d-one').one()
 eng.echo=True
 child.parent = parent
 child.name += ' MOVED'
 sess.commit()
 eng.echo=False
 print '# after'
 listd()
 
 initdb()
 tst3()


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-11 Thread Michael Bayer

0.5.0 final ?

On Jan 11, 2009, at 12:21 PM, Darren Govoni wrote:


 Hi MikeCo,
  I tried your example, and got this error from SA 0.5.

 ValueError: need more than 0 values to unpack

 Darren

 On Fri, 2009-01-09 at 20:33 -0800, MikeCo wrote:
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 dbname = ''
 dburl = 'sqlite:///%s' % dbname

 # set up environment
 eng = create_engine(dburl, echo=False)
 meta = MetaData(bind=eng)
 Base = declarative_base(metadata=meta)
 Session = sessionmaker()

 # D  self referential
 class D(Base):
__tablename__ = 'D'
id = Column(Integer, primary_key=True)
id_d = Column(Integer, ForeignKey('D.id'))
name = Column(Text)
child = relation('D',
backref=backref('parent', remote_side='D.id'))
def __repr__(self):
return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
 self.name)


 def initdb():
print '# create the database'
meta.drop_all(checkfirst=True)
meta.create_all()
sess = Session()

# insert some data for self-reference relationship
for ddata in ('d-one', 'd-two'):
dobj = D(name=ddata)
sess.add(dobj)
dobj2 = D(name=ddata+'-child1')
dobj.child.append(dobj2)
dobj2 = D(name=ddata+'-child2')
dobj.child.append(dobj2)
dobj3 = D(name=ddata+'-child2'+'-child3')
dobj2.child.append(dobj3)
sess.commit()
sess.close()

 def printobj(obj, indent=''):
# recursive list
print '%s%s' % (indent, obj)
if hasattr(obj, 'child'):
for ch in obj.child:
printobj(ch, indent=indent+'')

 def listd():
# retrieve and list
sess = Session()
print '# D-D'
query = sess.query(D).filter(D.id_d==None).order_by(D.name)
for dobj in query:
printobj(dobj)
sess.close()

 def tst3():
# do stuff with self referential class D
sess = Session()
print #switch parentage of name 'd-two-child1' to 'd-one'
print '# before'
listd()
child = sess.query(D).filter(D.name=='d-two-child1').one()
parent = sess.query(D).filter(D.name=='d-one').one()
eng.echo=True
child.parent = parent
child.name += ' MOVED'
sess.commit()
eng.echo=False
print '# after'
listd()

 initdb()
 tst3()


 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-11 Thread Darren Govoni

Ahhh, looks like I'm on rc4. Let me try final and see.

On Sun, 2009-01-11 at 13:10 -0500, Michael Bayer wrote:
 0.5.0 final ?
 
 On Jan 11, 2009, at 12:21 PM, Darren Govoni wrote:
 
 
  Hi MikeCo,
   I tried your example, and got this error from SA 0.5.
 
  ValueError: need more than 0 values to unpack
 
  Darren
 
  On Fri, 2009-01-09 at 20:33 -0800, MikeCo wrote:
  from sqlalchemy import *
  from sqlalchemy.orm import *
  from sqlalchemy.ext.declarative import declarative_base
 
  dbname = ''
  dburl = 'sqlite:///%s' % dbname
 
  # set up environment
  eng = create_engine(dburl, echo=False)
  meta = MetaData(bind=eng)
  Base = declarative_base(metadata=meta)
  Session = sessionmaker()
 
  # D  self referential
  class D(Base):
 __tablename__ = 'D'
 id = Column(Integer, primary_key=True)
 id_d = Column(Integer, ForeignKey('D.id'))
 name = Column(Text)
 child = relation('D',
 backref=backref('parent', remote_side='D.id'))
 def __repr__(self):
 return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
  self.name)
 
 
  def initdb():
 print '# create the database'
 meta.drop_all(checkfirst=True)
 meta.create_all()
 sess = Session()
 
 # insert some data for self-reference relationship
 for ddata in ('d-one', 'd-two'):
 dobj = D(name=ddata)
 sess.add(dobj)
 dobj2 = D(name=ddata+'-child1')
 dobj.child.append(dobj2)
 dobj2 = D(name=ddata+'-child2')
 dobj.child.append(dobj2)
 dobj3 = D(name=ddata+'-child2'+'-child3')
 dobj2.child.append(dobj3)
 sess.commit()
 sess.close()
 
  def printobj(obj, indent=''):
 # recursive list
 print '%s%s' % (indent, obj)
 if hasattr(obj, 'child'):
 for ch in obj.child:
 printobj(ch, indent=indent+'')
 
  def listd():
 # retrieve and list
 sess = Session()
 print '# D-D'
 query = sess.query(D).filter(D.id_d==None).order_by(D.name)
 for dobj in query:
 printobj(dobj)
 sess.close()
 
  def tst3():
 # do stuff with self referential class D
 sess = Session()
 print #switch parentage of name 'd-two-child1' to 'd-one'
 print '# before'
 listd()
 child = sess.query(D).filter(D.name=='d-two-child1').one()
 parent = sess.query(D).filter(D.name=='d-one').one()
 eng.echo=True
 child.parent = parent
 child.name += ' MOVED'
 sess.commit()
 eng.echo=False
 print '# after'
 listd()
 
  initdb()
  tst3()
 
 
  
 
 
  


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-10 Thread MikeCo

One thing to notice about ignoring the ids completely. This can
introduce inefficiencies when updating records. In the sample function
tst3() the line

child.parent = parent

causes SA to read the old parent record to get the attribute
child.parent. Changing to:

child.id_d = parent.id

eliminates the extra SELECT statement.

Inefficiencies like that are pretty rare.


On Jan 9, 11:33 pm, MikeCo mconl...@gmail.com wrote:
 I spent some time understanding this a little while ago. Here is the
 construct you need
 (thanks to Michael Bayer for making it clear for me)

 # D  self referential
 class D(Base):
     __tablename__ = 'D'
     id = Column(Integer, primary_key=True)
     id_d = Column(Integer, ForeignKey('D.id'))
     name = Column(Text)
     child = relation('D', backref=backref('parent',
 remote_side='D.id'))

 The 'child' relation establishes the two way linkage you want.

 One of the key things to think about is to use objects as normal
 python data structures. Generally you don't need to manipulate ids;
 let SQLAlchemy worry about that.

 Here is sample script I used when learning the topic

 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base

 dbname = ''
 dburl = 'sqlite:///%s' % dbname

 # set up environment
 eng = create_engine(dburl, echo=False)
 meta = MetaData(bind=eng)
 Base = declarative_base(metadata=meta)
 Session = sessionmaker()

 # D  self referential
 class D(Base):
     __tablename__ = 'D'
     id = Column(Integer, primary_key=True)
     id_d = Column(Integer, ForeignKey('D.id'))
     name = Column(Text)
     child = relation('D',
         backref=backref('parent', remote_side='D.id'))
     def __repr__(self):
         return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
 self.name)

 def initdb():
     print '# create the database'
     meta.drop_all(checkfirst=True)
     meta.create_all()
     sess = Session()

     # insert some data for self-reference relationship
     for ddata in ('d-one', 'd-two'):
         dobj = D(name=ddata)
         sess.add(dobj)
         dobj2 = D(name=ddata+'-child1')
         dobj.child.append(dobj2)
         dobj2 = D(name=ddata+'-child2')
         dobj.child.append(dobj2)
         dobj3 = D(name=ddata+'-child2'+'-child3')
         dobj2.child.append(dobj3)
     sess.commit()
     sess.close()

 def printobj(obj, indent=''):
     # recursive list
     print '%s%s' % (indent, obj)
     if hasattr(obj, 'child'):
         for ch in obj.child:
             printobj(ch, indent=indent+'    ')

 def listd():
     # retrieve and list
     sess = Session()
     print '# D-D'
     query = sess.query(D).filter(D.id_d==None).order_by(D.name)
     for dobj in query:
         printobj(dobj)
     sess.close()

 def tst3():
     # do stuff with self referential class D
     sess = Session()
     print #switch parentage of name 'd-two-child1' to 'd-one'
     print '# before'
     listd()
     child = sess.query(D).filter(D.name=='d-two-child1').one()
     parent = sess.query(D).filter(D.name=='d-one').one()
     eng.echo=True
     child.parent = parent
     child.name += ' MOVED'
     sess.commit()
     eng.echo=False
     print '# after'
     listd()

 initdb()
 tst3()
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

 On Jan 9, 10:03 pm, Darren Govoni dar...@ontrenet.com wrote:

  Hi,
    Thanks for the response. I'm still fairly new to SA but am very
  impressed with this package!

  I tried a variety of combinations of mappings. If I use just the
  parent_id,parent it would seem to make sense logically if my children
  only have one parent.

  The tables generate fine. But when I try to set the parent of a child at
  runtime it throws an exception about Conversion not being a list or
  collection or something. So I was experimenting with the M2M, and as you
  see, its not right.

  Logically, the self referring parent should be enough I would think. Is
  there another way using Base without having to use another mapping
  technique since all my other classes are Base derived?

  Thank you.

  On Fri, 2009-01-09 at 20:17 -0500, Michael Bayer wrote:

   On Jan 9, 2009, at 7:42 PM, project2501 wrote:

Hi,
 I'm trying to create a mapped class that allows parent/child
relation of itself. I've spent the last 3 hours searching and reading
the other posts on this, but can't get anything to work.

I'm on 0.5rc4 and just want to declare this in a mapped class as such:

class Conversion(Base):
   __tablename__ = 'conversion'

   id = Column(Integer, primary_key=True)
   name = Column(String(20))

   parent_id = Column(Integer, ForeignKey('conversion.id'))
   parent = relation(Conversion, backref=child)

   children = relation('Conversion', secondary=conversion_conversion,
backref='parents')

I was hoping to use the same style many-to-many declarations 

[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-10 Thread Darren Govoni

Interesting to know.

Appreciate the examples!

On Sat, 2009-01-10 at 05:38 -0800, MikeCo wrote:
 One thing to notice about ignoring the ids completely. This can
 introduce inefficiencies when updating records. In the sample function
 tst3() the line
 
 child.parent = parent
 
 causes SA to read the old parent record to get the attribute
 child.parent. Changing to:
 
 child.id_d = parent.id
 
 eliminates the extra SELECT statement.
 
 Inefficiencies like that are pretty rare.
 
 
 On Jan 9, 11:33 pm, MikeCo mconl...@gmail.com wrote:
  I spent some time understanding this a little while ago. Here is the
  construct you need
  (thanks to Michael Bayer for making it clear for me)
 
  # D  self referential
  class D(Base):
  __tablename__ = 'D'
  id = Column(Integer, primary_key=True)
  id_d = Column(Integer, ForeignKey('D.id'))
  name = Column(Text)
  child = relation('D', backref=backref('parent',
  remote_side='D.id'))
 
  The 'child' relation establishes the two way linkage you want.
 
  One of the key things to think about is to use objects as normal
  python data structures. Generally you don't need to manipulate ids;
  let SQLAlchemy worry about that.
 
  Here is sample script I used when learning the topic
 
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
  from sqlalchemy import *
  from sqlalchemy.orm import *
  from sqlalchemy.ext.declarative import declarative_base
 
  dbname = ''
  dburl = 'sqlite:///%s' % dbname
 
  # set up environment
  eng = create_engine(dburl, echo=False)
  meta = MetaData(bind=eng)
  Base = declarative_base(metadata=meta)
  Session = sessionmaker()
 
  # D  self referential
  class D(Base):
  __tablename__ = 'D'
  id = Column(Integer, primary_key=True)
  id_d = Column(Integer, ForeignKey('D.id'))
  name = Column(Text)
  child = relation('D',
  backref=backref('parent', remote_side='D.id'))
  def __repr__(self):
  return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
  self.name)
 
  def initdb():
  print '# create the database'
  meta.drop_all(checkfirst=True)
  meta.create_all()
  sess = Session()
 
  # insert some data for self-reference relationship
  for ddata in ('d-one', 'd-two'):
  dobj = D(name=ddata)
  sess.add(dobj)
  dobj2 = D(name=ddata+'-child1')
  dobj.child.append(dobj2)
  dobj2 = D(name=ddata+'-child2')
  dobj.child.append(dobj2)
  dobj3 = D(name=ddata+'-child2'+'-child3')
  dobj2.child.append(dobj3)
  sess.commit()
  sess.close()
 
  def printobj(obj, indent=''):
  # recursive list
  print '%s%s' % (indent, obj)
  if hasattr(obj, 'child'):
  for ch in obj.child:
  printobj(ch, indent=indent+'')
 
  def listd():
  # retrieve and list
  sess = Session()
  print '# D-D'
  query = sess.query(D).filter(D.id_d==None).order_by(D.name)
  for dobj in query:
  printobj(dobj)
  sess.close()
 
  def tst3():
  # do stuff with self referential class D
  sess = Session()
  print #switch parentage of name 'd-two-child1' to 'd-one'
  print '# before'
  listd()
  child = sess.query(D).filter(D.name=='d-two-child1').one()
  parent = sess.query(D).filter(D.name=='d-one').one()
  eng.echo=True
  child.parent = parent
  child.name += ' MOVED'
  sess.commit()
  eng.echo=False
  print '# after'
  listd()
 
  initdb()
  tst3()
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
  On Jan 9, 10:03 pm, Darren Govoni dar...@ontrenet.com wrote:
 
   Hi,
 Thanks for the response. I'm still fairly new to SA but am very
   impressed with this package!
 
   I tried a variety of combinations of mappings. If I use just the
   parent_id,parent it would seem to make sense logically if my children
   only have one parent.
 
   The tables generate fine. But when I try to set the parent of a child at
   runtime it throws an exception about Conversion not being a list or
   collection or something. So I was experimenting with the M2M, and as you
   see, its not right.
 
   Logically, the self referring parent should be enough I would think. Is
   there another way using Base without having to use another mapping
   technique since all my other classes are Base derived?
 
   Thank you.
 
   On Fri, 2009-01-09 at 20:17 -0500, Michael Bayer wrote:
 
On Jan 9, 2009, at 7:42 PM, project2501 wrote:
 
 Hi,
  I'm trying to create a mapped class that allows parent/child
 relation of itself. I've spent the last 3 hours searching and reading
 the other posts on this, but can't get anything to work.
 
 I'm on 0.5rc4 and just want to declare this in a mapped class as such:
 
 class Conversion(Base):
__tablename__ = 'conversion'
 
id = Column(Integer, primary_key=True)
name = Column(String(20))
 
parent_id = 

[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-09 Thread Michael Bayer


On Jan 9, 2009, at 7:42 PM, project2501 wrote:


 Hi,
  I'm trying to create a mapped class that allows parent/child
 relation of itself. I've spent the last 3 hours searching and reading
 the other posts on this, but can't get anything to work.

 I'm on 0.5rc4 and just want to declare this in a mapped class as such:

 class Conversion(Base):
__tablename__ = 'conversion'

id = Column(Integer, primary_key=True)
name = Column(String(20))

parent_id = Column(Integer, ForeignKey('conversion.id'))
parent = relation(Conversion, backref=child)

children = relation('Conversion', secondary=conversion_conversion,
 backref='parents')

 I was hoping to use the same style many-to-many declarations I do
 elsewhere. It creates fine, but doesn't work when adding objects.

The many-to-many is possible but is not really necessary for the  
typical self-referential mapping.  It depends on if you'd like a  
single object to have many parents.  However in your example above, it  
appears you are creating two separate self-referring bidirectional  
relationships, parent/child (which is also misconfigured, the many- 
to-one side needs a remote_side argument) and parents/children.
This would create two entirely isolated methods of associating one  
Conversion object with another - there's no link between parent/child  
and parents/children.  Is this the desired effect ?


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-09 Thread Darren Govoni

Hi,
  Thanks for the response. I'm still fairly new to SA but am very
impressed with this package!

I tried a variety of combinations of mappings. If I use just the
parent_id,parent it would seem to make sense logically if my children
only have one parent.

The tables generate fine. But when I try to set the parent of a child at
runtime it throws an exception about Conversion not being a list or
collection or something. So I was experimenting with the M2M, and as you
see, its not right.

Logically, the self referring parent should be enough I would think. Is
there another way using Base without having to use another mapping
technique since all my other classes are Base derived?

Thank you.

On Fri, 2009-01-09 at 20:17 -0500, Michael Bayer wrote:
 
 On Jan 9, 2009, at 7:42 PM, project2501 wrote:
 
 
  Hi,
   I'm trying to create a mapped class that allows parent/child
  relation of itself. I've spent the last 3 hours searching and reading
  the other posts on this, but can't get anything to work.
 
  I'm on 0.5rc4 and just want to declare this in a mapped class as such:
 
  class Conversion(Base):
 __tablename__ = 'conversion'
 
 id = Column(Integer, primary_key=True)
 name = Column(String(20))
 
 parent_id = Column(Integer, ForeignKey('conversion.id'))
 parent = relation(Conversion, backref=child)
 
 children = relation('Conversion', secondary=conversion_conversion,
  backref='parents')
 
  I was hoping to use the same style many-to-many declarations I do
  elsewhere. It creates fine, but doesn't work when adding objects.
 
 The many-to-many is possible but is not really necessary for the  
 typical self-referential mapping.  It depends on if you'd like a  
 single object to have many parents.  However in your example above, it  
 appears you are creating two separate self-referring bidirectional  
 relationships, parent/child (which is also misconfigured, the many- 
 to-one side needs a remote_side argument) and parents/children.
 This would create two entirely isolated methods of associating one  
 Conversion object with another - there's no link between parent/child  
 and parents/children.  Is this the desired effect ?
 
 
  


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalchemy@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
-~--~~~~--~~--~--~---



[sqlalchemy] Re: Self-Referential Mapping with Base?

2009-01-09 Thread MikeCo

I spent some time understanding this a little while ago. Here is the
construct you need
(thanks to Michael Bayer for making it clear for me)

# D  self referential
class D(Base):
__tablename__ = 'D'
id = Column(Integer, primary_key=True)
id_d = Column(Integer, ForeignKey('D.id'))
name = Column(Text)
child = relation('D', backref=backref('parent',
remote_side='D.id'))

The 'child' relation establishes the two way linkage you want.

One of the key things to think about is to use objects as normal
python data structures. Generally you don't need to manipulate ids;
let SQLAlchemy worry about that.

Here is sample script I used when learning the topic

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

dbname = ''
dburl = 'sqlite:///%s' % dbname

# set up environment
eng = create_engine(dburl, echo=False)
meta = MetaData(bind=eng)
Base = declarative_base(metadata=meta)
Session = sessionmaker()

# D  self referential
class D(Base):
__tablename__ = 'D'
id = Column(Integer, primary_key=True)
id_d = Column(Integer, ForeignKey('D.id'))
name = Column(Text)
child = relation('D',
backref=backref('parent', remote_side='D.id'))
def __repr__(self):
return '--D (id:%s-id_d:%s) %s --' % (self.id, self.id_d,
self.name)


def initdb():
print '# create the database'
meta.drop_all(checkfirst=True)
meta.create_all()
sess = Session()

# insert some data for self-reference relationship
for ddata in ('d-one', 'd-two'):
dobj = D(name=ddata)
sess.add(dobj)
dobj2 = D(name=ddata+'-child1')
dobj.child.append(dobj2)
dobj2 = D(name=ddata+'-child2')
dobj.child.append(dobj2)
dobj3 = D(name=ddata+'-child2'+'-child3')
dobj2.child.append(dobj3)
sess.commit()
sess.close()

def printobj(obj, indent=''):
# recursive list
print '%s%s' % (indent, obj)
if hasattr(obj, 'child'):
for ch in obj.child:
printobj(ch, indent=indent+'')

def listd():
# retrieve and list
sess = Session()
print '# D-D'
query = sess.query(D).filter(D.id_d==None).order_by(D.name)
for dobj in query:
printobj(dobj)
sess.close()

def tst3():
# do stuff with self referential class D
sess = Session()
print #switch parentage of name 'd-two-child1' to 'd-one'
print '# before'
listd()
child = sess.query(D).filter(D.name=='d-two-child1').one()
parent = sess.query(D).filter(D.name=='d-one').one()
eng.echo=True
child.parent = parent
child.name += ' MOVED'
sess.commit()
eng.echo=False
print '# after'
listd()

initdb()
tst3()
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



On Jan 9, 10:03 pm, Darren Govoni dar...@ontrenet.com wrote:
 Hi,
   Thanks for the response. I'm still fairly new to SA but am very
 impressed with this package!

 I tried a variety of combinations of mappings. If I use just the
 parent_id,parent it would seem to make sense logically if my children
 only have one parent.

 The tables generate fine. But when I try to set the parent of a child at
 runtime it throws an exception about Conversion not being a list or
 collection or something. So I was experimenting with the M2M, and as you
 see, its not right.

 Logically, the self referring parent should be enough I would think. Is
 there another way using Base without having to use another mapping
 technique since all my other classes are Base derived?

 Thank you.

 On Fri, 2009-01-09 at 20:17 -0500, Michael Bayer wrote:

  On Jan 9, 2009, at 7:42 PM, project2501 wrote:

   Hi,
    I'm trying to create a mapped class that allows parent/child
   relation of itself. I've spent the last 3 hours searching and reading
   the other posts on this, but can't get anything to work.

   I'm on 0.5rc4 and just want to declare this in a mapped class as such:

   class Conversion(Base):
      __tablename__ = 'conversion'

      id = Column(Integer, primary_key=True)
      name = Column(String(20))

      parent_id = Column(Integer, ForeignKey('conversion.id'))
      parent = relation(Conversion, backref=child)

      children = relation('Conversion', secondary=conversion_conversion,
   backref='parents')

   I was hoping to use the same style many-to-many declarations I do
   elsewhere. It creates fine, but doesn't work when adding objects.

  The many-to-many is possible but is not really necessary for the  
  typical self-referential mapping.  It depends on if you'd like a  
  single object to have many parents.  However in your example above, it  
  appears you are creating two separate self-referring bidirectional  
  relationships, parent/child (which is also misconfigured, the many-
  to-one side needs a remote_side argument) and parents/children.    
  This would create two entirely isolated methods