Yes I totally agree with you. If Topic was mapped to a specific user then I
would go that route. In my case it is a shared entity across users, but the
projects are specific to a user. So the query changes based on which user
is logged in.
Querying for a specific set of M projects out of the total N projects
associated to a Topic is very simple with a relationship with explicit
primaryjoin condition or by making the relationship with dynamic and
putting the required filter clause.
My current requirement is a little quirky because I wanted a mapped
property on the Topic entity, whereas I can have the following to get the
results too.
query = select([func.count(...).label('proj_count')]).where(.....user
clause....)
topics = session.query(Topic, query)
topics = topics.all()
But then the result of this will be a KeyedTuple and I have to access the
tuple with its keys. I just cant pass the single Topic entity and have the
count data associated with it. I would have to the handle the KeyedTuple in
every place. I will try out some more options and see what best can be done.
Thanks,
Mainak
On Saturday, December 13, 2014 9:04:56 AM UTC-8, Michael Bayer wrote:
>
>
> On Dec 12, 2014, at 10:58 PM, Mainak Sarcar <[email protected]
> <javascript:>> wrote:
>
> Yes Mike, you are right. Once the object is created and flushed, it has
> the database identity. But the column_property was never accessed. So there
> is no value for the property in the __dict__. Now if I try to access the
> parameter, it fires the query with the unset bindparam and I get the
> exception. Is there a way to set the bindparam value before I access the
> property for the first time on the object?
>
> BTW here is what my model looks like.
>
> Topic
> - id
> - name
> - project_count (column property with bindparam for user_id)
> - projects (relationship)
>
> Project
> - id
> - name
> - topic_id (FK to Topic)
> - user_id
> - status
>
>
> Well what immediately doesn’t make sense is that what does
> Topic.project_count mean if there is no user_id that is local to Topic?
> the Topic has N number of projects, but you only want M, those with some
> arbitrary user_id. So it makes no sense to use column_property for this.
> You need to pass in user_id to a function as an argument. Suppose
> column_property did what you wanted, now Topic.project_count is “10”. But
> now user_id, somewhere on the outside, changes to something else. Now
> Topic.project_count is incorrect. It doesn’t make sense for this to be a
> “mapped” value, because Topic has no fixed user_id.
>
> OTOH if user_id were part of Topic then you’d just use a correlated
> subquery as you see in
> http://docs.sqlalchemy.org/en/rel_0_9/orm/mapper_config.html#using-column-property
> .
>
> i think basically it doesn’t make any sense to use a dynamically bound
> parameter with column_property().
>
>
> I have a REST endpoint for Topic. When I create a new Topic instance, I
> emit the json version of the object. That is where the column_property gets
> accessed for the first time. Now in reality, there wont be any projects
> when the Topic is created, so firing a query is not really required.
>
> I did give "hybrid property" a try initially using a
> func.count(Topic.projects). But that did not fire a count query, instead
> fired the complete query for fetching projects. I even tried to make
> Topic.projects a "dynamic" load, so that I can pass the extra where clause
> for user_id and status etc. Then I gave column_property a try based on the
> example.
>
> Regards
> Mainak
>
>
> On Fri, Dec 12, 2014 at 9:44 AM, Michael Bayer <[email protected]
> <javascript:>> wrote:
>>
>>
>> On Dec 12, 2014, at 7:11 AM, Mainak Sarcar <[email protected]
>> <javascript:>> wrote:
>>
>> Hi,
>>
>> I have a column_property defined on a model with a select expression as
>> explained in the examples in
>> http://docs.sqlalchemy.org/en/latest/orm/mapper_config.html#using-column-property.
>>
>> I had to add an extra condition to the where clause with a bindparam. I
>> have also defined the column_property with the "deferred=True", so that the
>> query is not fired in the first place.
>>
>> I am able to perform queries by using the "undefer" option in the query
>> instance and also passing the param to the query. But when I create an
>> instance of the model and flush and then try to access the column_property,
>> the query tries to get fired and throws exception complaining about the
>> bindparam value not being passed.
>>
>>
>> Is there a way I can explicitly prevent the column_property query being
>> fired for an object that is newly created.
>>
>>
>> I’m puzzled here, the object is flushed, meaning it now has a database
>> identity. Then, I’m assuming either the column_property has never been
>> accessed before, so there is no value in __dict__, or you did a commit(),
>> which expired everything, so there’s nothing in __dict__. Then you access
>> it, which implies you’d like it to return a value of some kind. However,
>> the property has an unset bound parameter. What would the correct value
>> be? If there is no correct value, then what are you expecting to happen
>> when you access this property?
>>
>> It sounds like what you really want here is a hybrid:
>> http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/hybrid.html
>>
>>
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.