I want to run 2 queries in django, I am using mysql, Please help me
first one
SELECT * FROM `invitations`
WHERE post_id = 19215 GROUP BY (user_id)
it is not group by from user_id
data = Invitations.objects.filter(post_id=19215).annotate(user_id=Count('user_id'))
now i have add value
data = Invitations.objects.values('user_id').filter(post_id=19215).annotate(user_id=Count('user_id'))
it return me not all fields select *
data = Invitations.objects.values('user_id', 'xyz').filter(post_id=19215).annotate(user_id=Count('user_id'))
it group by user_id and xyz
Please give me solution
and second is
SELECT *, GROUP_CONCAT(interview_mode) FROM invitations WHERE post_id = 19215 GROUP BY (user_id)
Run this:
query= "SELECT *, GROUP_CONCAT(interview_mode)
FROM invitations WHERE post_id = 19215
GROUP BY (user_id)"
data = Model.objects.raw(query)
Related
I have 2 models, Product and Productdetails with a OneToOne relationship like this:
class Product(IotaModel):
details = models.OneToOneField(
ProductDetails,
null=True,
on_delete=models.SET_NULL
)
I want a queryset that do this:
SELECT *
FROM product_details
WHERE id = (
SELECT details_id
FROM products
WHERE id=<product_id>
)
I tried this:
details_id = Product.objects.filter(pk=product_pk, active=True).only('details')[:1]
return ProductDetails.objects.filter(pk=details_id, active=True)
But it does not work becouse .only('details') gave me the fields (id, details_id) and the next filter takes id instead of details_id.
I also try to add .defer('id') but that does not work.
I know that I can get the details_id using .values_list('details_id') but I think this would involve making 2 queries to the Database.
What could be the best approach to reach the desired SQL query in just 1 hit to the DB?
Thanks in advance!
You should make just the query for the ProductDetails. Something like this I think.
product_details = ProductDetails.objects.get(
active=True, product__id=product_pk, product__active=True
)
The double underscore it's to look on related objects.
I have a model with simple relation
class Tasks(models.Model):
initiator = models.ForeignKey(User, on_delete = models.CASCADE)
class TaskResponsiblePeople(models.Model):
task = models.ForeignKey('Tasks')
auth_user = models.ForeignKey(User)
And I need to write an analogue of an SQL query as follows:
select a.initiator, b.auth_user
from Tasks a
inner join TaskResponsiblePeople b
on TaskResponsiblePeople.task_id = task.id
where Tasks.initiator = 'value A' OR TaskResponsiblePeople.auth_user = 'value B'
The problem is that the OR statement deals with two different tables and I've got no idea about the right Django syntax to mimique the above-stated raw-SQL query. Help me out please !
UPDATE 1
According to the below-stated answer, I use the following code:
people = TaskResponsiblePeople.objects.filter(Q(task__initiator = request.user.id)|Q(auth_user = request.user.id)).select_related('auth_user')
print people.query
# The result of the print copy-pasted from console
# SELECT * FROM `task_responsible_people`
# LEFT OUTER JOIN `tasks` ON (`task_responsible_people`.`task_id` = `tasks`.`id`)
# LEFT OUTER JOIN `auth_user` T4
# ON (`task_responsible_people`.`auth_user_id` = T4.`id`)
# WHERE (`tasks`.`initiator_id` = 7 OR
# 'task_responsible_people`.`auth_user_id` = 7)
tasks = Tasks.objects.prefetch_related(
Prefetch('task_responsible_people', queryset=people, to_attr='people'))
However, in the final resultset I can still see records where neither initiator nor auth_user are equal to request.user (equal to 7 in this case)
I avoid using ".values" because of the potential need to serialize and transform the queryset into json.
I think you can do it this way if you just want those specific columns:
from django.db.models import Q
qs = Tasks.objects.filter(Q(initiator=userA) | Q(taskresponsiblepeople__auth_user=userB))\
.values('initiator', 'taskresponsiblepeople__auth_user')
To examine the generated query you can look at:
print(qs.query)
I don't have the models in my database but it should generate a query similar to following:
SELECT "tasks"."initiator_id", "taskresponsiblepeople"."auth_user_id"
FROM "tasks" LEFT OUTER JOIN "taskresponsiblepeople"
ON ( "tasks"."id" = "taskresponsiblepeople"."tasks_id" )
WHERE ("tasks"."initiator_id" = userA_id
OR "taskresponsiblepeople"."auth_user_id" = userB_id))
I have a model with two foreign keys on another one.
DB structure:
class LightUsers(models.Model):
admin = models.ForeignKey(User, db_index=True, related_name="lightuser_admin")
user = models.ForeignKey(User, db_index=True, related_name="lightuser_user")
class User(models.Model):
...
I want to perform query like:
SELECT * FROM lightusers INNER JOIN user ON (lightusers.admin_id = user.id) WHERE lightusers.user_id IN ( 1, 2, 3)
To achieve this I wrote next code:
light_users = LightUsers.objects.filter(user__in=[1,2,3]).select_related('user')
But Django translates this code in query with join by another foreign key field. Like this:
SELECT * FROM lightusers INNER JOIN user ON (lightusers.user_id = user.id) WHERE lightusers.user_id IN ( 1, 2, 3)
Is there a way to force Django use Foreign Key that I want. Or raw query is the only option?
I need to get data from user table by ids in admin column
IF you want this, then you just have to use the admin field:
light_users = LightUsers.objects.filter(admin__in=[1,2,3])
but that's not the same as:
I want to perform query like:
SELECT * FROM lightusers INNER JOIN user ON (lightusers.admin_id = user.id) WHERE lightusers.user_id IN ( 1, 2, 3)
This basically means give me all lightusers with user_id IN ( 1, 2, 3) and having an admin. In an ORM fashion this can be achieved like so:
light_users = LightUsers.objects.filter(
user_id__in=[1,2,3], #this will filter lightusers.user_id IN ( 1, 2, 3)
admin__isnull=False #this will INNER JOIN users on admin and get row having an admin
)
Well in the end i gave up to make this in one query. And divided it into two:
relations = LightUsers.objects.filter(user__in=[1, 2, 3]).values_list('admin_id', 'user_id')
light_users = User.objects.filter(id__in=[relation[0] for relation in relations])
And then combined result.
I have Contacts and ContactsGroup Two models
contact contains group as m2m relationship
class ContactGroup(models.Model):
contact_group = models.ManyToManyField(ContactGroup, null=True, related_name="contact_list")
and contacts is another model
I want to create bulk_create contacts where contact_group also added on the model.
group_list = []
if group:
groups = [item.strip() for item in group.split(',')]
for item in groups:
try:
group, created = ContactGroup.objects.get_or_create(account=account, name=item)
group_list.append(group)
except :
pass
contact = Contacts(
name = name,
phone = change_phone_format(phone),
email = email,
address = address,
company = company,
website = website,
notes = notes,
dob = dob,
account = account
)
bulk_obj.append(contact)
bulk_group.append(group_list)
ThroughModel = Contacts.contact_group.through
now_date = datetime.datetime.now()
Contacts.objects.bulk_create(bulk_obj)
contacts = Contacts.objects.filter(created_on__gte=now_date)
bulk_through = []
for i, item in enumerate(contacts):
for gr in bulk_group[i]:
if item and gr:
bulk_through.append(ThroughModel(contactgroup_id=item.pk, contacts_id=gr.pk))
ThroughModel.objects.bulk_create(bulk_through)
But shows error
IntegrityError at /contact-manager/contacts/process/goIKlkpymfWCaFeiQXwp/
(1452, 'Cannot add or update a child row: a foreign key constraint fails (`sparrow`.`contactmanager_contacts_contact_group`, CONSTRAINT `D3781be41803f836ec292e41ed99c16a` FOREIGN KEY (`contactgroup_id`) REFERENCES `contactmanager_contactgroup` (`id`))')
Is there any solution ?
Maybe this can help, change last but one line to:
bulk_through.append(ThroughModel(contactgroup_id=gr.pk, contacts_id=item.pk))
seems to me that variables are mixed.
I have a problem. I have to do this query:
#app.route('/api/subscriptions/<string:id>', methods=('DELETE',))
#decorators.login_required
def delete_subscription(id):
dbsession = DBSession()
session = Session()
favorit = (dbsession.query(StudentsFavorites)
.filter(Exams.number == str(id))
.filter(StudentsFavorites.exam_id)
.filter(Students.id == StudentsFavorites.student_id)
.filter(Students.id == str(session.get_user_id()))
.delete() )
dbsession.flush()
return jsonify(error=False)
But when I do this query I get this exception:
OperationalError: (OperationalError) no such column: exams.number u'DELETE FROM students_favorites WHERE exams.number = ? AND students_favorites.exam_id AND students.id = students_favorites.student_id AND students.id = ?' ('123123123', 'a24213')
The tables are very big and got lots of information, so i can't post all of it. But this query works:
#app.route('/api/subscriptions/<string:id>', methods=('PUT',))
#decorators.login_required
def add_subscription(id):
dbsession = DBSession()
session = Session()
examID = (dbsession.query(Exams.id)
.filter(Exams.number == id).first()
)
favorit=StudentsFavorites(student_id=session.get_user_id(), exam_id=examID.id)
dbsession.add(favorit)
dbsession.flush()
return jsonify(error=False)
Short view to the table:
table: Exams
rows: id, number (number is the id i put into the function)
table: StudentsFavorites
rows: student_id, exams_id
table: Students
rows: id
I really didn't understand, why he didn't find the number row in the exception.
EDIT:
Database StudentsFavorites:
class StudentsFavorites(Base):
"""N:M resolve model for the exams to the semester.
"""
__tablename__ = "students_favorites"
student_id = Column(Unicode(255), ForeignKey("students.id"), primary_key=True, autoincrement=False)
exam_id = Column(Integer, ForeignKey("exams.id"), primary_key=True, autoincrement=False)
created_at = Column(DateTime, nullable = False, default = datetime.now)
student = relationship("Students", uselist = False, lazy="joined")
exam = relationship("Exams", uselist=False, lazy="joined")
Something like this? I tried this:
(dbsession.query(StudentsFavorites)
.filter(StudentsFavorites.exam.id == str(id))
.filter(StudentsFavorites.student.id == str(session.get_user_id()))
.delete()
)
But got the error, that id didn't exist in exams / student
You have two cases of the same problem. Your query has information for StudentFavorites which means it knows about StudentFavorites.student_id and StudentFaovrites.exams_id. It doesn't know anything about Students.id, Exames.id and Exames.number. In order for you to query a StudentFavorites object and have it know about those other values you're going to have to perform a sql join.
Join's can be a bit of a pain in the ass to get working in sqlalchemy (well... in regular sql as well). Since I don't know what your table schema is I can't talk about that but the view should look something like this.
#app.route('/api/subscriptions/<string:id>', methods=('DELETE',))
#decorators.login_required
def delete_subscription(id):
dbsession = DBSession()
session = Session()
favorit = (dbsession.query(StudentsFavorites)
.join(Exames)
.join(students)
.filter(Exams.number == str(id))
.filter(StudentsFavorites.exam_id)
.filter(Students.id == StudentsFavorites.student_id)
.filter(Students.id == str(session.get_user_id()))
.delete() )
dbsession.flush()
return jsonify(error=False)
Alternatively, you can look into setting up Foreign key relationships in your table statements if you use the ORM to create your tables
The reason your second example works is because you're specifying a query over an exam table and only using values found in that table.
Response to Edit:
Right now your table relationships aren't set up correctly. Specifically the sections: Many To Many and Deleting Rows from the Many to Many Table
This example code is explained in much more (and better) detail in the posted link but the basic idea is that you have a associate_table (in your case StudentFavorites) contains foreign keys which have a relationship which is specified in one or more of your other tables. I personally advise that you go with the table example and not the object example.
association_table = Table('association', Base.metadata,
Column('left_id', Integer, ForeignKey('left.id')),
Column('right_id', Integer, ForeignKey('right.id'))
)
class Parent(Base):
__tablename__ = 'left'
id = Column(Integer, primary_key=True)
children = relationship("Child",
secondary=association_table,
backref="parents")
class Child(Base):
__tablename__ = 'right'
id = Column(Integer, primary_key=True)