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:[email protected]
> 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 [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.
--
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.