On Oct 27, 2010, at 12:50 PM, Torsten Landschoff wrote:

> Replacing the Sheet class and following code like this, I can at least access 
> the names list as if it really was a simple list.
> 
> class Sheet(Base):
>     __tablename__ = "sheet"
>     sheet_id = Column("sheet_id", Integer, primary_key=True)
>     # List of names
>     _names = relation(Name,
>             order_by=[Name.position],
>             collection_class=ordering_list('position'),
>             cascade="save-update, merge, delete, delete-orphan")
>     names = association_proxy("_names", "value")
>     # ... more columns
> 
> engine = create_engine("sqlite:///", echo=True)
> Base.metadata.create_all(engine)
> 
> Session = sessionmaker(bind=engine)
> 
> session = Session() 
> sheet = Sheet()
> sheet.names = ["Foo", "Bar", "Baz"]
> session.add(sheet)
> session.commit()
> 
> session = Session()
> sheet = session.query(Sheet).one()
> assert sheet.names == ["Foo", "Bar", "Baz"]
> 
> sheet.names[1:1] = ["Add", "Two"]
> session.commit()
> 
> session = Session()
> sheet = session.query(Sheet).one()
> assert sheet.names == ["Foo", "Add", "Two", "Bar", "Baz"]
> 
> But this code is too unwieldy  IMHO. What I would like to have is something 
> like
> 
> class Sheet(object):
>     ...
>     names = make_ordered_list("names", String)
> 
> But I failed to implement this. I can only think of gross hacks to make that 
> work (like going up the stack frame and finding the type instance). Any hints 
> on how to make this happen?

Configuration is too unwieldy ?   Since you're using declarative , just using 
@declared_attr would give you access to the class:

def make_ordered_list(key, pk, type_):
    @declared_attr
    def go(cls):
        class Name(Base):
            __tablename__ = "%s_names" % key
            rel_id = Column("related_id", Integer, ForeignKey(pk), 
                            primary_key=True, index=True)
            position = Column("position",  Integer)
            value = Column("value", type_, primary_key=True)
            def __init__(self, value):
                self.value = value
        private_key = "_" + key
        
        setattr(cls, key, association_proxy(private_key, "value"))
        
        return relation(
                                    Name, 
                                    order_by=Name.position, 
                                    collection_class=ordering_list('position')
                                )
        Name.__name__ = '%sName' % key
        
    return go
        
class Sheet(Base):
    __tablename__ = "sheet"
    sheet_id = Column("sheet_id", Integer, primary_key=True)
    
    _names = make_ordered_list("names", sheet_id, String)


if you wanted to get rid of saying "_names", you need to create something that 
is added after the fact:

Sheet.names = make_ordered_list(Sheet, ...)

or class decorator:

@stores_names('names')
class Sheet(...)

This because the class is not mapped, and no mapper exists, until the class has 
been constructed.  Declarative lets you get to the mapper using the class-bound 
attributes, with @declared_attr the path towards one that is dynamic.  So this 
is sort of an issue of you'd like more hooks into declarative's interpretation 
of mapper().

On that note, if you're ambitious, you could make a wrapper around mapper() and 
give that to declarative_base() as its "mapper" argument, which looks for 
special attributes on the class and generates additional properties.










> 
> Greetings, Torsten
> 
> -- 
> DYNAmore Gesellschaft fuer Ingenieurdienstleistungen mbH
> Torsten Landschoff
> 
> Office Dresden
> Tel: +49-(0)351-4519587
> Fax: +49-(0)351-4519561
> 
> mailto:torsten.landsch...@dynamore.de
> http://www.dynamore.de
> 
> Registration court: Mannheim, HRB: 109659, based in Karlsruhe,
> Managing director:  Prof. Dr. K. Schweizerhof, Dipl.-Math. U. Franz
> 
> -- 
> 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