On Mon, Aug 27, 2012 at 4:16 PM, Jacob Biesinger
<jake.biesin...@gmail.com>wrote:

> On Mon, Aug 27, 2012 at 3:56 PM, Michael Bayer 
> <mike...@zzzcomputing.com>wrote:
>
>>
>> On Aug 27, 2012, at 3:54 PM, Michael Bayer wrote:
>>
>>
>> On Aug 27, 2012, at 3:50 PM, Jacob Biesinger wrote:
>>
>> Hi all,
>>
>> Re-asking a question from stackoverflow here.
>> http://stackoverflow.com/questions/12148503/arbitrary-collections-in-sqlalchemy-with-referential-integrity
>>
>> I'm converting a library to use SA as the datastore. I like the
>> flexibility of the PickleType column, but it doesn't seem to work well when
>> pickling SA objects (table rows).  Even if I overload setstate and getstate
>> to do a query + session merge when unpickling, there's no referential
>> integrity across that pickle boundary.  That means that I can't query
>> collections of objects.
>>
>> class Bar(Base):
>>     id = Column(Integer, primary_key=True)
>>     __tablename__ = 'bars'
>>     foo_id = Column(Integer, ForeignKey('foos.id'), primary_key=True)
>>
>> class Foo(Base):
>>     __tablename__ = 'foos'
>>     values = Column(PickleType)
>>     #values = relationship(Bar)  # list interface (one->many), but can't
>> assign a scalar or use a dictionary
>>     def __init__(self):
>>         self.values = [Bar(), Bar()]
>>
>>         # only allowed with PickleType column
>>         #self.values = Bar()
>>         #self.values = {'one' : Bar()}
>>         #self.values = [ [Bar(), Bar()], [Bar(), Bar()]]
>>
>> # get all Foo's with a Bar whose id=1
>> session.query(Foo).filter(Foo.values.any(Bar.id == 1)).all()
>>
>> One workaround would be to implement my own mutable object type as is
>> done here:
>> https://github.com/ccat/sqlalchemy_examples/blob/master/mutable_example/mutable_alwayUpdate.py#L51
>>  and
>> to have some kind of flattening scheme which traverses the collections and
>> appends them to a simpler one->many relationship.  Perhaps the flattened
>> list might have to be weakrefs to the pickled collection's objects?
>>  Tracking changes and references sounds like no fun.  Any advice?
>>
>>
>> The PickleType is really a hacky way around edge cases where you have
>> some arbitrary object you'd just like to shove away.     It's a given that
>> when you use PickleType, you're giving up any relational advantages,
>> including being able to filter/query on them, etc.
>>
>> So putting an ORM mapped object in a Pickle is basically a terrible idea.
>>
>> Point taken.
>
>>
>> If you want a collection of scalar values, use traditional mappings and
>> relationship() in combination with association_proxy.  See
>> http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/associationproxy.html#simplifying-scalar-collections.
>>
>>
>> re: "or dictionaries".  Use attribute_mapped_collection:
>> http://docs.sqlalchemy.org/en/rel_0_7/orm/collections.html#dictionary-collections
>>
>> "dictionaries plus scalars": combine both attribute_mapped_collection and
>> association_proxy:
>> http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/associationproxy.html#proxying-to-dictionary-based-collections
>>
>> Thanks, I saw this example before but hadn't thought of it in this way.
>  I suppose the creator here could be a polymorphic vertical column as in
> http://www.sqlalchemy.org/trac/browser/examples/vertical/dictlike-polymorphic.py,
> which could act as a scalar, as a list, or as a dictionary depending on an
> introspected type.  Querying such a collection seems like it would be a
> pain though.
>

Is the use case of having nested collections really all that out of
mainstream?  It seems like a fairly straightforward requirement, though
perhaps with a lot of boilerplate.  A simple list-of-lists seems achievable
using something like:

all_lists = Table('all_lists', metadata,
                    Column('id', Integer, primary_key=True),
                    Column('type', String(32)),  # polymorphic type... one
of 'list' or 'scalar'
                    Column('scalar_id', Integer, ForeignKey('scalars.id')),
                    Column('list_id', Integer, ForeignKey('all_lists.id')))

with an appropriate polymorphic identifier.  Am I going down a dead-end
here?

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

Reply via email to