I've used answer from this question:
Django: making raw SQL query, passing multiple/repeated params?
but have some problems.
I have params:
params = {'film_id_string': 'core_film.parent_id', 'tags_params': 'comedy', 'order_by': 'core_film.title', 'content_type': '18', 'language_code': 'en'}
for SQL query:
query = 'SELECT DISTINCT "core_object".*, "core_film".* FROM "core_film" INNER JOIN "core_object" ON ("core_film"."parent_id" = "core_object"."id") LEFT OUTER JOIN "core_objectlocalized" ON ("core_objectlocalized"."parent_id" = %(film_id_string)s) LEFT OUTER JOIN "tagging_taggeditem" ON ("tagging_taggeditem"."object_id" = "core_objectlocalized"."id") LEFT OUTER JOIN "tagging_tag" ON ("tagging_tag"."id" = "tagging_taggeditem"."tag_id") WHERE "tagging_tag"."name" IN (%(tags_params)s) AND "core_objectlocalized"."LANG"=%(language_code)s AND content_type_id=%(content_type)s ORDER BY %(order_by)s'
When I tried to use RawQuerySet
films = Film.objects.raw(query, params)
I get:
SELECT DISTINCT "core_object".*, "core_film".*
FROM "core_film"
INNER JOIN "core_object" ON ("core_film"."parent_id" = "core_object"."id")
LEFT OUTER JOIN "core_objectlocalized" ON ("core_objectlocalized"."parent_id" = E\'core_film.parent_id\')
LEFT OUTER JOIN "tagging_taggeditem" ON ("tagging_taggeditem"."object_id" = "core_objectlocalized"."id")
LEFT OUTER JOIN "tagging_tag" ON ("tagging_tag"."id" = "tagging_taggeditem"."tag_id")
WHERE "tagging_tag"."name" IN (E\'comedy\')
AND "core_objectlocalized"."LANG"=E\'en\'
AND content_type_id=E\'18\'
ORDER BY E\'core_film.title\'
Problem is, that every place with 'E\' generate error similar to this:
DatabaseError: invalid input syntax for integer: "core_film.parent_id"
LINE 1: ...calized" ON ("core_objectlocalized"."parent_id" = E'core_fil...
How can I fix this?
Django version 1.2.3.
edit
I can't remove quotes, because I work with string:
result = self.function(result, tag, "core_film.parent_id")
def function(self, objects, tags, film_id_string):
My params for RawQuerySet look like this:
params = {'film_id_string': film_id_string}
When I try to parse this I get:
LEFT OUTER JOIN "core_objectlocalized" ON ("core_objectlocalized"."parent_id" = E\'core_film.parent_id\')
and then I have problems with
DatabaseError: invalid input syntax for integer: "core_film.parent_id"
LINE 1: ...calized" ON ("core_objectlocalized"."parent_id" = E'core_fil...
but, when I use string formatting
LEFT OUTER JOIN "core_objectlocalized" ON ("core_objectlocalized"."parent_id" = %s)' % film_id_string
it works:
LEFT OUTER JOIN "core_objectlocalized" ON ("core_objectlocalized"."parent_id" = core_film.parent_id)
I want to ommit posibility of SQL injection, so basing on Django docs I don't want to pass params with string formatting.
What can I else do?
Django prevents SQL interjection by escaping parameters. This is an SQL statement, therefore the fact that it does not work is a good thing - Django is doing it's job. Unless the users of the system will be setting the value for "film_id_string" what you did to get it to work should be ok. If not, then you would have to still used the "...%s)' % film_id_string..." method but create your own custom filter to validate that it is one of the correct allowed values.
Related
I have below python method which insert data in to a table. the first column is json_data and the 2nd column is file name. I am getting both the values to this function while calling this method from main.
def insert(sf_handler,data,file_name):
query = """INSERT INTO my_table (DATA,FILE_NAME)
(select (PARSE_JSON('%s'),'%s'))""" % {json.dumps(data),file_name)}
pd.read_sql(query,sf_handler)
But while executing this i am getting below error. Can someone help on this.
TypeError: not enough arguments for format string
I got the answer. Just type cast the file name and remove the flower bracket with parenthesis it will work.
query = """INSERT INTO my_table (DATA,FILE_NAME)
(select (PARSE_JSON('%s'),'%s'))""" % (json.dumps(data),str(file_name))
pd.read_sql(query,sf_handler)
I have 3 models Product,Photo,ProductLikeDislike. I am left joining all the three. For that I wrote this query:
x=Product.objects.values_list('name','photo','productlikedislike')
Through this I am getting correct left join I printed and checked like this:
Note: olx is the name of my Django app.
print(x.query)
SELECT "olx_product"."name", "olx_photo"."id", "olx_productlikedislike"."id"
FROM "olx_product" LEFT OUTER JOIN "olx_photo" ON ("olx_product"."id" =
"olx_photo"."reference_id_id") LEFT OUTER JOIN "olx_productlikedislike" ON
("olx_product"."id" = "olx_productlikedislike"."product_id_id") ORDER BY
"olx_product"."created" DESC
Now I want to add extra and condition along with ON statement like this:
ON ("olx_product"."id" =
"olx_productlikedislike"."product_id_id"
and "olx_productlikedislike"."product_liked_by_id"=2)
So for this somebody suggested me that use Django's FilteredRelation. I used but it is not adding extra and condition along with ON
I used FilteredRelation like this:
x=Product.objects.annotate(
productlikedislike_product_liked_by_id=FilteredRelation('productlikedislike',
condition=Q(productlikedislike__product_liked_by_id=2))).values_list('name',
'photo','productlikedislike')
but getting the same sql query no extra and condition. I am using Django 2.1.5
I got the answer by adding 'productlikedislike_product_liked_by_id' to the values_list(...) that I am using along with FilteredRelation.
So the final query is:
x=Product.objects.filter(Q(photo__cover_photo_flag="yes")|Q(photo__file=None)).annotate(
productlikedislike_product_liked_by_id=FilteredRelation('productlikedislike',condition=Q(pr
oductlikedislike__product_liked_by_id=2))).values_list('name','photo','productlikedislike_p
roduct_liked_by_id')
I printed it it is giving me this resul which I wanted to get:
SELECT "olx_product"."name", "olx_photo"."id",
productlikedislike_product_liked_by_id."id" FROM "olx_product" LEFT OUTER JOIN
"olx_photo" ON ("olx_product"."id" = "olx_photo"."reference_id_id") LEFT OUTER JOIN
"olx_productlikedislike" productlikedislike_product_liked_by_id ON ("olx_product"."id" =
productlikedislike_product_liked_by_id."product_id_id" AND
(productlikedislike_product_liked_by_id."product_liked_by_id_id" = 2)) WHERE
("olx_photo"."cover_photo_flag" = yes OR "olx_photo"."file" IS NULL) ORDER BY
"olx_product"."created" DESC
I have 2 models: Task and TaskLimit. Task belongs to TaskLimit. But task_limit_id might be Nil, so I need to use LEFT JOIN to preload existing TaskLimit's.
The only way I can do join is this:
query = query.join(:task_limit).preload(:task_limit)
But It doesn't select Tasks without TaskLimit.
There is a method in source code of Query class, where I can specify String for my JOIN:
def self.join(join_string : String)
self.new.join(join_string)
end
But When I try to use it:
query.join("LEFT JOIN task_limits ON tasks.task_limit_id = task_limits.id").preload(:task_limit)
I get an error that the method doesn't exist:
in tmp/1537794230627_console.cr:2: no overload matches 'Crecto::Repo::Query#join' with type String
Overloads are:
- Crecto::Repo::Query#join(join_associations : Array(Symbol))
- Crecto::Repo::Query#join(join_association : Symbol)
query = query.join("LEFT JOIN task_limits ON tasks.task_limit_id = task_limits.id").preload(:task_limit).where(id: [43, 46])
How can I preload association with LEFT JOIN?
I have this ActiveRecord query:
Stock.select('DISTINCT ON (stocks.part_number)*').joins(:part, :manufacturer)
.includes(:manufacturer, :part).order(:part_number).with_cat(category).
where(manufacturers: {abbr: ['manufacturer1', 'manufacturer2']})
with_cat is a scope:
scope :with_cat, -> (category) { where(parts: {category_id: category}) }
Now the reason I am using Distinct on is because every manufacturer can have the same part as another, hence duplicates. I do not want duplicates. The above gets the job done. Except when I add count to it I get an error.
PG::SyntaxError: ERROR: syntax error at or near "ON"
LINE 1: SELECT COUNT(DISTINCT ON (stocks.part_number)*) FROM "stocks...
^
: SELECT COUNT(DISTINCT ON (stocks.part_number)*) FROM "stocks"
INNER JOIN "parts" ON "parts"."id" = "stocks"."part_id"
INNER JOIN "manufacturers" ON "manufacturers"."id" = "stocks"."manufacturer_id"
WHERE "parts"."category_id" = 17 AND "manufacturers"."abbr" IN ('manufacturer1', 'manufacturer2')
Not really sure how to add a count to the query without causing that error. I'm not familiar with Distinct on either. Any explanation as to why this is happening would be great!
Does it fix the query if you use the count ahead of distinct? Got the idea per this postgres documentation.
Stock.select('count(distinct part_number)')...
I'm using the sqlite3 library in c++ to query the database from *.sqlite file. can you write a query statement in sqlite3 like:
char* sql = "select name from table id = (select full_name from second_table where column = 4);"
The second statement should return an id to complete the query statement with first statement.
Yes you can, just make sure that the nested query doesn't return more than one row. Add a LIMIT 1 to the end of the nested query to fix this. Also make sure that it always returns a row, or else the main query will not work.
If you want to match several rows in the nested query, then you can use either IN, like so:
char* sql = "select name from table WHERE id IN (select full_name from second_table where column = 4);"
or you can use JOIN:
char* sql = "select name from table JOIN second_table ON table.id = second_table.full_name WHERE second_table.column = 4"
Note that the IN method can be very slow, and that JOIN can be very fast, if you index on the right columns
On a sidenote, you can use SQLiteadmin (http://sqliteadmin.orbmu2k.de/) to view the database and make queries directly in it (useful for testing etc).