Filtering by relation count in SQLAlchemy - python

I'm using the SQLAlchemy Python ORM in a Pylons project. I have a class "Project" which has a one to many relationship with another class "Entry". I want to do a query in SQLAlchemy that gives me all of the projects which have one or more entries associated with them. At the moment I'm doing:
[project for project in Session.query(Project) if len(project.entries)>0]
which I know isn't ideal, but I can't figure out how to do a filter that does what I require (e.g. Session.query(Project).filter(Project.entries.exists())).
Any ideas?

Session.query(Project).filter(Project.entries.any()) should work.
Edited credit of James Brady's comment, be sure to give him some love.

Related

Create a Django REST API from a class diagram

From the knowledge I have, one has two approaches: code first or database first.
There are frameworks where one defines the models and the relationships, and auto migrate creates the database in the mirror of what one has defined.
Tried to find something reverse, but appears to me that Django does what I mentioned first - if one created the class models and migrated, then Django would create the entity database model for us.
Considering I started with the database, I don't know anything automatic to do this or the best way to tackle it.
You have two different ways to do that from the Class Diagram:
• Create the models and do the migration to create the DB.
• Create the DB and then integrate it just like you would do with a Legacy DB - as it shows in Jon Clements comment .

Partial Query of a django JSONField

I have a model with a django JSONField. The JSONField has a key called 'name'. I want to search across my model, for users whose names contain Foo; something like :
User.objects.filter(jsonfield['name']__icontains='foo')
As far as I have researched there is no easy way to do this. My next alternative is to add a new column for jsonfield['name'] so I can search it. Although the fix I am looking for needs to be quick, I am also open to know my more involved options so I can refactor later. Thank you.

How to add many to one relationship with model from external application in django

My django project uses django-helpdesk app.
This app has Ticket model.
My app got a Client model, which should have one to many relationship with ticket- so I could for example list all tickets concerning specific client.
Normally I would add models.ForeignKey(Client) to Ticket
But it's an external app and I don't want to modify it (future update problems etc.).
I wold have no problem with ManyToMany or OneToOne but don't know how to do it with ManyToOne (many tickets from external app to one Client from my app)
Even more hacky solution: You can do the following in the module level code after you Client class:
class Client(models.Model):
...
client = models.ForeignKey(Client, related_name='tickets')
client.contribute_to_class(Ticket, name='client')
I haven't fully tested it (I didn't do any actual database migrations), but the correct descriptors (ReverseSingleRelatedObjectDescriptor for Ticket and ForeignRelatedObjectsDescriptor for Client) get added to the class, and South recognizes the new fields. So far it seems to work just like a regular ForeignKey.
EDIT: Actually not even that hacky. This is exactly how Django sets up foreign keys across classes. It just reverses the process by adding the field when the reverse related class is built. It won't raise an error if any of the original fields on either model is shadowed. Just make sure you don't do that, as it could potentially break your code. Other than that, I don't think there should be any issues.
There are (at least) two ways to accomplish it:
More elegant solution: Use a TicketProfile class which has a one-to-one relation to Ticket, and put the Client foreign key into it.
Hacky solution: Use a many-to-many relation, and manually edit the automatically created table and make ticket_id unique.

Django: queryset multiple conditions or gather into new object

I need to get all Comments for all Projects that includes a specific User. Meaning, all comments for all projects that a user is member of.
A user can belong to many Projects, and each Project has many Comments.
How should this be done right? So far I have solved it in my template by creating a nested for-loop, but that's not good since I need to sort the result.
I'm thinking something like:
projects = user.projects
comments = Comment
for p in projects:
for c in p.comments:
comments.append(c)
return comments
...does not seem to work.
Any clues?
I think this will do it:
query = Comment.objects.filter(project__user=person)
If the Comment model has a foreign key to project which has a foreign key to user. This will involve a SQL join statement in the database. It's better to do this on the the database because it's far more efficient. Databases are designed exactly to do this.

Custom sql for Django model

A bit of background...
I'm trying to create a custom auth backend and extend the user model. I'm using the following as a blue print:
blog post by Scott Barnham
For whatever reason, the ORM is generating invalid sql. It seems to want to do a inner join back to itself and it's failing because it can't find a field named user_ptr_id for the join.
If you do a search for this, it seems that I might not be the only one. And there is actually a reference to this in a comment on the blog post above. But, I can't seem to fix it.
It seems like I should be able to override the SQL that is getting generated. Is that correct? From what I can tell, it seem like I might do this with a custom Object manager. Correct?
However, I can't seem to find a good example of what I want to do. Everything that I see is wanting to inherit and chain them. That's not really what I want to do. I sort of just want to say something like:
hey Django! on a select, use this SQL statement. etc
Is this possible? Maybe my "googlin'" is off today, but I can't seem to find it. That leads me to believe I'm using wrong terms or something.
Please note: I'm using Django 1.3.1 with Python 2.6.5 and PostgreSQL 9.1
David,
Yes, you can override the behavior of a model by implementing an overriding Manager in the object. I found a great blog by Greg Allard on A Django Model Manager for Soft Deleting Records which runs through a soft delete, to set a field deleted to True/False and only show objects that are not deleted, or all with deleted objects.
With that in mind, I would think you could override your object's all(), or filter() methods to get what you want. As an aside, everytime I have used a pointer, "ptr" is evident in the name of the field, it is because of class inheritance. For example, class Animal():..., class Man(Animal): Man extends or is a subclass of Animal. In the database, the Man table will have an animal_ptr_id which "extends" the animal table's tuple with that id as a Man with ANIMAL fields and MAN fields JOINed.

Categories