Explication Models and queries in django - sql

I have question and problem at the same time, I have two models in deferents, projects like this
PROJECT: TransactionMaster.models => TransactionMaster
class TransactionMaster(models.Model):
user = models.ForeignKey(User, on_delete=CASCADE)
trans_status = models.BooleanField()
trans_name = models.CharField()
PROJECT: TransactionDetails.models => TransactionDetail
from app.transactionMaster.models import TransactionMaster
class TransactionDetail(models.Model):
transaction = models.ForeignKey(TransactionMaster, on_delete=CASCADE)
current_status = models.IntegerField()
transdetail_name = models.CharField()
how Can I do the next sql query
SELECT * FROM User as u inner join TransactionMaster as tm in u.id=tm.user_id inner join TransactionDetail as td in tm=td.transaction_id where tm.trans_status=td.current_status
and
SELECT * FROM TransactionMaster as tm inner join TransactionDetail as td in tm.id=td.transaction_id where tm.trans_status=td.current_status
I try the second query like this:
TransactionDetail.object.filter(TransactionMaster__id=transaction_id, trans_status=TransactionMaster__current_status)
Please help me with this queries, and could you answer me what can I do in models in the different project, please.
thanks for your attention
Angel Rojas

For both queries, it seems that you want to get the TransactionMaster records that have at least one TransactionDetail record with a curent_status that is equal to the trans_status of the TransactionMaster.
In Django, that may translate to:
from django.db.models import F
transaction_masters = TransactionMaster.objects.filter(transactiondetail__current_status=F('trans_status'))
For the first query it looks as though you are interested in the users of the TransactionMaster records? To get the users, just extract them from the filtered transaction_masters.
users = [tm.user for tm in transaction_masters]

Related

How to filter all objects that contain multiple elements in a many-to-many relationship using Django's ORM?

I have two classes in Django linked through a ManyToManyField (the User class is the built-in User model):
from django.contrib.auth.models import User
class Activity():
participants = models.ManyToManyField(User, related_name='activity_participants')
I want to find all the activities in which two users are simultaneously participating.
I managed to solve my problem using a raw query (my app name is "core", therefore the "core" prefix in the table names):
SELECT ca.id FROM core_activity_participants AS cap, core_activity AS ca
INNER JOIN core_activity_participants AS cap2 ON cap.activity_id
WHERE cap.user_id == 1 AND cap2.user_id == 2
AND cap.activity_id == cap2.activity_id
AND ca.id == cap.activity_id
However, if possible, I'd like to avoid using raw queries, since it breaks uniformity from the rest of my app. How could I make this query, or one equivalent to it, using Django's ORM?
If you're using Django 1.11 or later the intersection queryset method will give you the records you want.
# u1 and u2 are User instances
u1_activities = Activity.objects.filter(participants=u1)
u2_activities = Activity.objects.filter(participants=u2)
common_activities = u1_activities.intersection(u2_activities)
Will produce a query something like this:
SELECT "core_activity"."id"
FROM "core_activity"
INNER JOIN "core_activity_participants"
ON ("core_activity"."id" = "core_activity_participants"."activity_id")
WHERE "core_activity_participants"."user_id" = 1
INTERSECT
SELECT "core_activity"."id"
FROM "core_activity"
INNER JOIN "core_activity_participants"
ON ("core_activity"."id" = "core_activity_participants"."activity_id")
WHERE "core_activity_participants"."user_id" = 2
You can also add extra querysets to the intersection if you want to check for activity overlap between more than 2 users.
Update:
Another approach, which works with older Django versions, would be
u1_activities = u1.activity_participants.values_list('pk', flat=True)
common_activities = u2.activity_participants.filter(pk__in=u1_activities)
Which produces a query like
SELECT "core_activity"."id"
FROM "core_activity"
INNER JOIN "core_activity_participants"
ON ("core_activity"."id" = "core_activity_participants"."activity_id")
WHERE (
"core_activity_participants"."user_id" = 2
AND "core_activity"."id" IN (
SELECT U0."id"
FROM "core_activity" U0
INNER JOIN "core_activity_participants" U1
ON (U0."id" = U1."activity_id")
WHERE U1."user_id" = 1
)
)

How manage outer join, group_by and count with Django

Using Django I have the follow models:
class Player(models.Model):
name = models.CharField(max_length=64)
description = models.CharField(max_length=128)
groupPlayer = models.ForeignKey(GroupPlayer)
class GroupPlayer(models.Model):
description = models.CharField(max_length=128)
name = models.CharField(max_length=32)
Every player is linked to a group. Some group has no player. My aim is to translate the follow query in Django (which include LEFT OUTER JOIN and Group by):
select GroupPlayer.description, GroupPlayer.name, COUNT(Player.name) as gplayer
from (GroupPlayer LEFT OUTER JOIN Player ON GroupPlayer.id = Player.groupPlayer_id)
GROUP BY GroupPlayer.id
So far I have created 3 queryset, but I cannot put them together in order to get the result I wish:
queryset_player = Player.objects.values('groupPlayer_id').annotate(total=Count('groupPlayer__id'))
queryset_group = GroupPlayer.objects.select_retated(queryset_player)
queryset_group2 = GroupPlayer.objects.all().prefetch_related('player_set')
Anyone can help with that LEFT OUTER JOIN, Group by and count?
Thanks
from django.db.models import Count
groups = GroupPlayer.objects.annotate(num_players=Count('player'))
groups[0].num_players
Aggragation

How to join dbo.LocalizedLabelView to get form labels in Dynamics CRM?

In Dynamics CRM, I often get requirements from business users to create reports. Business users know and speak about entity display names and attribute labels. To write a query, I need to map those to entity names and attribute names. I would like to use a query to look this up.
To what do I join the dbo.LocalizedLabelView view to get the AttributeLabel column in the following query? I can't figure out what ObjectId is supposed to reference. (And if you can tell me how you figured out the answer I'd be especially appreciative!)
select
[EntityName] = entityNames.Name,
[EntityDisplayName] = entityDisplayNames.Label,
[AttributeName] = attributeNames.PhysicalName,
[AttributeDisplayName] = attributeDisplayNames.Label
--[AttributeLabel] = attributeLabels.Label
from
dbo.EntityView entityNames
inner join dbo.LocalizedLabelView entityDisplayNames
on entityDisplayNames.ObjectId = entityNames.EntityId
and entityDisplayNames.ObjectColumnName = 'LocalizedName'
left outer join dbo.AttributeView attributeNames
on attributeNames.EntityID = entityNames.EntityID
inner join dbo.LocalizedLabelView attributeDisplayNames
on attributeDisplayNames.ObjectId = attributeNames.AttributeID
and attributeDisplayNames.ObjectColumnName = 'DisplayName'
and attributeDisplayNames.LanguageID = entityDisplayNames.LanguageID
--inner join dbo.LocalizedLabelView attributeLabels
-- on attributeLabels.ObjectId = ?????
-- and attributeLabels.LanguageID = entityDisplayNames.LanguageID
where
entityDisplayNames.LanguageID = 1033
order by
entityDisplayNames.Label,
attributeDisplayNames.Label
ObjectId is a reference to the internal ID of a thing in the CRM database. This thing can be an attribute, entity, label, or whatever.
Since you want the label for your attribute, use that attribute's id as the ObjectId here. I think that you want your join condition to look like this:
inner join dbo.LocalizedLabelView attributeLabels
on attributeLabels.ObjectId = attributeNames.AttributeID
and attributeLabels.LanguageID = entityDisplayNames.LanguageID
and attributeLabels.ObjectColumnName = 'DisplayName'
If you want the description for the attribute, you can change the ObjectColumnName to 'Description'.

fetching single child row based on a max value using Django ORM

I have a model, "Market" that has a one-to-many relation to another model, "Contract":
class Market(models.Model):
name = ...
...
class Contract(models.Model):
name= ...
market = models.ForeignKey(Market, ...)
current_price = ...
I'd like to fetch Market objects along with the contract with the maximum price of each. This is how I'd do it via raw SQL:
SELECT M.id as market_id, M.name as market_name, C.name as contract_name, C.price
as price from pm_core_market M INNER JOIN
(SELECT market_id, id, name, MAX(current_price) as price
FROM pm_core_contract GROUP BY market_id) AS C
ON M.id = C.market_id
Is there a way to implement this without using SQL? If there is, which one should be preferred in terms of performance?
Django 1.1 (currently beta) adds aggregation support to the database API. Your query can be done like this:
from django.db.models import Max, F
Contract.objects.annotate(max_price=Max('market__contract__current_price')).filter(current_price=F('max_price')).select_related()
This generates the following SQL query:
SELECT contract.id, contract.name, contract.market_id, contract.current_price, MAX(T3.current_price) AS max_price, market.id, market.name
FROM contract LEFT OUTER JOIN market ON (contract.market_id = market.id) LEFT OUTER JOIN contract T3 ON (market.id = T3.market_id)
GROUP BY contract.id, contract.name, contract.market_id, contract.current_price, market.id, market.name
HAVING contract.current_price = MAX(T3.current_price)
The API uses an extra join instead of a subquery (like your query does). It is difficult to tell which query is faster, especially without knowing the database system. I suggest that you do some benchmarks and decide.

NHibernate Query problem

I'm quite new to NHibernate and starting to find my way around.
I have a domain model that is somewhat like a tree.
Funds have Periods have Selections have Audits
Now I would like to get all Audits for a specific Fund
Would look like this if I made it in SQL
SELECT A.*
FROM Audit A
JOIN Selection S ON A.fkSelectionID = S.pkID
JOIN Period P ON S.fkPeriodID = P.pkID
JOIN Fund F ON P.fkFundID = F.pkID
WHERE F.pkID = 1
All input appreciated!
Try this
select elements(s.Audits)
from Fund as f inner join Period as p inner join Selection as s
where f = myFundInstance
session.CreateCriteria ( typeof(Audit) )
.CreateCriteria("Selection")
.CreateCriteria("Period")
.CreateCriteria("Fund")
.Add(Restrinction.IdEq(fundId))
using LINQ ....
(from var p in Fund.Periods
let fundPeriodSelections = p.Selections
from var selection in fundPeriodSelections
select selection.Audit).ToList()
... but it does depend on those many-to-many / one-to-many relations being 2-way. Also, I was thinking you may need a mapping table / class in bewteen the Period / Fund table.. but I guess you've already considered it.
Hope the LINQ statemanet above works ... it depends on those mentioend properties, but it's an apraoch we've used on our project that's really cleaned up the code.