On Aug 3, 2010, at 3:37 AM, Enrico wrote:

> I'm trying to use the object association pattern from the doco. Is it
> the case that this requires departure from Declarative mode and is it
> wrong to mix with non-declarative?

it is perfectly fine to mix non-declarative with declarative.  However, it is 
almost always not necessary to use non_primary=True.   non_primary is when you 
want to have an alternative SELECT statement for a particular entity, and you 
need that SELECT wrapped in a mapping so that it can be used in a 
relationship().


> I looked at the example code
> optimized_al.py but it didn't seem to be exactly what I want. I want a
> symmetric relation for adjacency of nodes in an undirected graph with
> cycles. ie. it is not a tree.

The key to using association object is that you are no longer using the 
"secondary" attribute of relationship() (and hence no secondaryjoin).    
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import *
from sqlalchemy.orm import sessionmaker, relationship
Base = declarative_base()

class Node(Base):
   __tablename__ = 'node'
   id = Column(Integer, primary_key=True)


class Adj(Base):
    __tablename__ = 'adj'
    
    node_id = Column(Integer(), ForeignKey('node.id'),
                            primary_key=True)
                            
    adj_node_id = Column(Integer(), ForeignKey('node.id'),
                            primary_key=True)
                            
    node = relationship(Node, primaryjoin=node_id==Node.id,
                                backref='adj_node')
    adj_node = relationship(Node,
                        primaryjoin=adj_node_id==Node.id,
                        backref='node')
    
    def __str__(self):
        return "Adj(node=%s, adj_node=%s)" % (self.node_id, self.adj_node_id)
        
engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)

sess = sessionmaker(engine)()

n1, n2, n3 = Node(), Node(),Node()

n1.node.append(Adj(node=n2))
n1.node.append(Adj(node=n3))


sess.add_all([
    n1, n2, n3
])

sess.commit()

print sess.query(Adj).all()







> <code>
> class Node(DeclarativeBase):
>    __tablename__ = 'node'
>    #with some columns id etc.
> 
> adj = Table(u'adj', metadata,
>    Column(u'node', Integer(), ForeignKey('node.id'),
> primary_key=True),
>    Column(u'adj_node', Integer(), ForeignKey('node.id'),
> primary_key=True),
>    Column(u'somedata_id', Integer(), ForeignKey('somedata.id')),
> )
> class Adj(object):
>    __table__ = _adj
>    #relation definitions
>    node = relation('node')  # self-referential, bidirectional, many-
> to-many
>    somedata = relation('SomeData')
> 
>    def __init__(self, n1, n2):
>        self.n1 = n1
>        self.n2 = n2
> 
> mapper(Adj, adj, properties={
>    'node': relation(Adj,
>                       primaryjoin = Node.id==Adj.node,
>                       #secondaryjoin = Node.id==Adj.adj_node?,
>                       backref=backref('adj_node',
> remoteside=[_adj.c.node])
>                     )
>                             }, non_primary=True)
> </code>
> 
> I put the non_primary and the primaryjoin in after error messages told
> me to but now this is causing another error 'Adj' has not attribute
> 'node' I even tried primaryjoin = Node.id==adj.c.node but then I got
> "Could not locate any equated, locally mapped column pairs." This
> seems to be getting a bit more  complicated than it should be already.
> Is there an example of an association object in Declarative style?
> Also, is it possible to do it with forward references only?
> 
> -- 
> 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.
> 

-- 
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.

Reply via email to