AND in LEFT JOIN with Doctrine - doctrine-orm

How can i add AND in LEFT JOIN like this SELECT * FROM photo LEFT JOIN liked_photo lp on photo.id = lp.photo_id AND lp.user_id = 6 WHERE photo.is_public = 1 ?
`{`
`return $this->createQueryBuilder('photo')`
`->leftJoin("photo.likedPhotos", "lp", "photo.id = lp.Photo")`
`->addSelect('lp')`
`->where('photo.is_public = 1')`
`->orderBy('photo.uploaded_at', 'DESC')`
`->getQuery();`
}

Try with :
return $this->createQueryBuilder('photo')
->leftJoin("photo.likedPhotos", "lp", Join::WITH, "photo.id = lp.Photo AND lp.user_id = 6")
->addSelect('lp')
->where('photo.is_public = 1')
->orderBy('photo.uploaded_at', 'DESC')
->getQuery();
See doctrine doc : https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/query-builder.html#line-number-5775ab09aefa638b14c776a733b4b61d2e324b74-43

Related

Django queryset from raw SQL

I want an equivalent of this sql query in Django
SELECT Gender, ServCode
FROM [openimisproductTestDb_16_08_22].[dbo].[tblInsuree]
JOIN [openimisproductTestDb_16_08_22].[dbo].[tblServices] ON [openimisproductTestDb_16_08_22].[dbo].[tblInsuree].AuditUserID = [openimisproductTestDb_16_08_22].[dbo].[tblServices].AuditUserID
WHERE Gender = 'F'
AND ServCode = 'F4'
What I have tried:
def assisted_birth_with_cs_query(user, **kwargs):
date_from = kwargs.get("date_from")
date_to = kwargs.get("date_to")
hflocation = kwargs.get("hflocation")
format = "%Y-%m-%d"
date_from_object = datetime.datetime.strptime(date_from, format)
date_from_str = date_from_object.strftime("%d/%m/%Y")
date_to_object = datetime.datetime.strptime(date_to, format)
date_to_str = date_to_object.strftime("%d/%m/%Y")
dictBase = {
"dateFrom": date_from_str,
"dateTo": date_to_str,
}
dictGeo = {}
if hflocation and hflocation!="0" :
hflocationObj = HealthFacility.objects.filter(
code=hflocation,
validity_to__isnull=True
).first()
dictBase["fosa"] = hflocationObj.name
claimItem = Insuree.objects.filter(
validity_from__gte = date_from,
validity_to__lte = date_to,
**dictGeo,
gender = 'F'
).count()
data = Service.objects.filter(code = 'F4').count() | Insuree.objects.filter(gender = 'F').count()
dictGeo['health_facility'] = hflocationObj.id
dictBase["post"]= str(data)
return dictBase
I tried like that but the one just adds when I want the women included in the insured table and the F4 code contained in the service table. both tables have the auditUserID column in common
It would be great if you could add the models to better see the relations between Insuree and Service. Assuming it's a 1-M, I'd go with this query:
Service.objects.filter(code='F4', insuree__gender='F').count()

what is this error? need more than 1 value to unpack

I am getting the error need more than 1 value to unpack i am using defaultDict to make my list to dictionary.
def getTabsCols(request):
proj_name = request.GET.get('projname')
cursor = connection.cursor()
proj_details = TProjects.objects.get(
attr_project_name=proj_name, attr_project_type='Structure', attr_is_active=1)
pid = proj_details.project_id
query = 'call SP_Get_TABCOL_NAMES('+str(pid)+')'
cursor.execute(query)
proj_details = TProjects.objects.get(
attr_project_name=proj_name, attr_project_type='Structure', attr_is_active=1)
pid = proj_details.project_id
query = 'call SP_Get_TABCOL_NAMES('+str(pid)+')'
cursor.execute(query)
result = cursor.fetchall()
tab_list = []
tab_col_list = []
prd = {}
res = []
for row in result:
tabs = collections.OrderedDict()
schema_name = row[1]
table_name = row[3]
tab = (schema_name + '.' + table_name).encode('utf8')
tabs[tab] = row[5].encode('utf8')
tab_list.append(tabs)
d = collections.defaultdict(set)
for k, v in tab_list:
d1[k].append(v)
d = dict((k, tuple(v)) for k, v in d1.iteritems())
return HttpResponse(d, content_type="text/html")

Can you use django extra(select={}) to select multiple fields?

I am trying to add two new fields to my django product queryset and I do something like this
products = Product.objects.filter(company=company).filter(Q(name__icontains=search_term) | Q(code__icontains=search_term))
products = products.extra(select={"is_distributed": product_is_distributed_query(False)})
products = products.extra(select={"expense_type": product_expense_type_query(False)})
But the two queries (product_is_distributed_query and product_expense_type_query) are identical just returning different fields. Can I do this in only one extra(select{}) by using just one query to return both fields?
The query would be like this:
def product_is_distributed_query(use_product_code):
product_query = """
select vt.is_distributed, coalesce(et.name, '')
from (
SELECT
cp.id,
CASE WHEN SUM(coalesce(snp.id, 0)) > 0 THEN true
ELSE false
END as is_distributed,
max(coalesce(snp.expense_type_id, 0)) as maxId1
FROM
core_product AS cp
LEFT JOIN
stock_non_product AS snp
ON (cp.name = snp.name """
product_query = product_query + ("AND cp.code = snp.code" if use_product_code else "")
product_query += """
AND cp.company_id = snp.company_id AND snp.is_deleted = false)
LEFT JOIN expense_type as et ON(snp.expense_type_id = et.id AND snp.company_id = et.company_id)
WHERE
cp.id = core_product.id
AND cp.company_id = core_product.company_id
-- AND snp.company_id = core_product.company_id
GROUP BY
cp.id
) as vt
-- LEFT JOIN stock_non_product AS snp ON(snp.id = maxId)
LEFT JOIN expense_type as et ON(et.id = vt.maxId)
"""
return product_query
instead of being two separated queries that are identical to this one but return one or the other field

Can I trust Django's bulk_create to preserve order?

When I do something like this:
model_list = [Model(name = 'First'), Model(name = 'Second'), Model(name = 'Third')]
Model.objects.bulk_create(model_list)
Can I trust that they will be created in that same order?
That is:
pk1 = Model.objects.get(name = 'First').pk
pk2 = Model.objects.get(name = 'Second').pk
pk3 = Model.objects.get(name = 'Third').pk
(pk3 > pk2) and (pk2 > pk1)
I think you can.
model_list = [Model(name = 'First'),
Model(name = 'Second'),
Model(name = 'Third')]
Model.objects.bulk_create(model_list)
This code will be translated to the following SQL:
INSERT INTO app_model (name) VALUES ('First'), ('Second'), ('Third')
It is very unlikely that regular SQL server will insert these rows in different order.

Django Filter Loop OR

Does anyone know how I get Django Filter build an OR statement? I'm not sure if I have to use the Q object or not, I thought I need some type of OR pipe but this doesn't seem right:
filter_mfr_method = request.GET.getlist('filter_mfr_method')
for m in filter_mfr_method:
designs = designs.filter(Q(mfr_method = m) | m if m else '')
# Or should I do it this way?
#designs = designs.filter(mfr_method = m | m if m else '')
I would like this to be:
SELECT * FROM table WHERE mfr_method = 1 OR mfr_method = 2 OR mfr_method = 3
EDIT: Here is what Worked
filter_mfr_method = request.GET.getlist('filter_mfr_method')
list = []
for m in filter_mfr_method:
list.append(Q(mfr_method = m))
designs = designs.filter(reduce(operator.or_, list))
What about:
import operator
filter_mfr_method = request.GET.getlist('filter_mfr_method')
filter_params = reduce(operator.or_, filter_mfr_method, Q())
designs = designs.filter(filter_params)
Something I used before:
qry = None
for val in request.GET.getlist('filter_mfr_method'):
v = {'mfr_method': val}
q = Q(**v)
if qry:
qry = qry | q
else:
qry = q
designs = designs.filter(qry)
That is taken from one of my query builders.