raw query with primary key - python

My model
class Despacho (models.Model):
bus=models.ForeignKey(Bus)
contador = models.IntegerField()
cerrado = models.BooleanField(editable=False)
class Bus(models.Model):
numero_bus=models.CharField(max_length=255,unique=True)
en_ruta = models.BooleanField(editable=False)
I need a query to extract the data which I save a bus, and I enter a
number of the bus and I need to know if there is a dispatch that
matches the search try to do the following query
my database is postgresql
d = Despacho.objects.raw('''SELECT * FROM operaciones_despacho WHERE operaciones_despacho.bus = '%s' AND operaciones_despacho.cerrado = '%s'
;'''%(bus.numero_bus,False))
error : column operaciones_despacho.bus does not exist

First up in Django, we use raw sql only in the rare instances when it's particularly hard to write an ORM query. In this instance, writing an ORM query is much easier and shorter than a raw query.
Despacho.objects.filter(bus=bus).filter(cerrado=False)
On those rare instances when you need to do a raw query, take care you use the params argument to raw instead of string formatting. The correct way to write your raw query is
Despacho.objects.raw('''SELECT * FROM operaciones_despacho WHERE operaciones_despacho.bus = '%s' AND operaciones_despacho.cerrado = '%s'''' ,
[bus.numero_bus,False])
But I emphasis once again that you should not be using a raw query here because it's a simple ORM query.

Related

sql query to python django query

I'm new to Django and SQL. I have this following SQL query. How to implement the same in the Django query?
"SELECT DISTINCT C1.CLASSDESC AS CLASS,C2.CLASSCODE AS CODE, C1.CARDCATEGORY AS CATEGORY, C2.CLASSBENEFITS BENEFITS FROM CARDCLASSMAPPING C1,CARDCLASSMASTER C2 WHERE C1.ISACTIVE = 1 AND C2.ISACTIVE = 1 AND C1.CLASSDESC = C2.CLASSDESC AND C1.SCHEMETYPE = ? AND C1.SCHEMECODE = ? AND C1.GLCODE = ? AND C1.ACCOUNTCATEGORY = ? ORDER BY CLASS";
You can go through this link to understand how queries can be constructed in Django. Django provides ORM API to fetch data from your database easily using queries like this:
CardClassMapping.objects.get(id=1)
In order to use the above line of code, you should have a model named CardClassMapping to get the objects from.
Also, you can use raw SQL like this:
CardClassMapping.objects.raw('SELECT DISTINCT C1.CLASSDESC AS CLASS,C2.CLASSCODE AS CODE, C1.CARDCATEGORY AS CATEGORY, C2.CLASSBENEFITS BENEFITS FROM CARDCLASSMAPPING C1')
For more on raw SQL: https://docs.djangoproject.com/en/3.1/topics/db/sql/

MySql read_sql python query with variable #

I am aware that queries in Python can be parameterized using either ? or %s in execute query here or here
However I have some long query that would use some constant variable defined at the beginning of the query
Set #my_const = 'xyz';
select #my_const;
-- Query that use #my_const 40 times
select ... coalesce(field1, #my_const), case(.. then #my_const)...
I would like to do the least modif possible to the query from Mysql. So that instead of modifying the query to
pd.read_sql(select ... coalesce(field1, %s), case(.. then %s)... , [my_const, my_const, my_const, ..]
,I could write something along the line of the initial query. Upon trying the following, however, I am getting a TypeError: 'NoneType' object is not iterable
query_str = "Set #null_val = \'\'; "\
" select #null_val"
erpur_df = pd.read_sql(query_str, con = db)
Any idea how to use the original variable defined in Mysql query ?
The reason
query_str = "Set #null_val = \'\'; "\
" select #null_val"
erpur_df = pd.read_sql(query_str, con = db)
throws that exception is because all you are doing is setting null_value to '' and then selecting that '' - what exactly would you have expected that to give you? EDIT read_sql only seems to execute one query at a time, and as the first query returns no rows it results in that exception.
If you split them in to two calls to read_sql then it will in fact return you the value of your #null value in the second call. Due to this behaviour read_sql is clearly not a good way to do this. I strongly suggest you use one of my suggestions below.
Why are you wanting to set the variable in the SQL using '#' anyway?
You could try using the .format style of string formatting.
Like so:
query_str = "select ... coalesce(field1, {c}), case(.. then {c})...".format(c=my_const)
pd.read_sql(query_str)
Just remember that if you do it this way and your my_const is a user input then you will need to sanitize it manually to prevent SQL injection.
Another possibility is using a dict of params like so:
query_str = "select ... coalesce(field1, %(my_const)s, case(.. then %(my_const)s)..."
pd.read_sql(query_str, params={'my_const': const_value})
However this is dependent on which database driver you use.
From the pandas.read_sql docs:
Check your database driver documentation for which of the five syntax
styles, described in PEP 249’s paramstyle, is supported. Eg. for
psycopg2, uses %(name)s so use params={‘name’ : ‘value’}

How do I use Oracle schema names in Pony ORM?

This is the query that I need:
SELECT * FROM SCHEMA.LOT
Using the following Python code
class Lot(db.Entity):
_table_ = 'SCHEMA.LOT'
lot_key = PrimaryKey(int)
lot_id = Required(str)
this is the query that Pony ORM generates:
SELECT "l"."LOT_KEY", "l"."LOT_ID"
FROM "SCHEMA.LOT" "l"
Which naturally errors out with ORA-00942: table or view does not exist, because Oracle thinks that SCHEMA.LOT is the full table name. What I really need is for Pony ORM to generate a combination of the schema and the table name delimited by a dot that is not part of the string. So any of the following will work:
"SCHEMA"."LOT"
"SCHEMA".LOT
SCHEMA."LOT"
I've tried to trick Pony ORM by defining _table_ as 'SCHEMA"."LOT', but it just automatically converts this into the broken "SCHEMA"".""LOT". Infuriating!
Is there any way around this?
PonyORM does this because the dot is a valid name symbol.
In order to specify compound name you need to define table name as a list of strings:
class Lot(db.Entity):
_table_ = ['SCHEMA', 'LOT']
lot_key = PrimaryKey(int)
lot_id = Required(str)

Django model search concatenated string

I am trying to use a Django model to for a record but then return a concatenated field of two different tables joined by a foreign key.
I can do it in SQL like this:
SELECT
location.location_geoname_id as id,
CONCAT_WS(', ', location.location_name, region.region_name, country.country_name) AS 'text'
FROM
geonames_location as location
JOIN
geonames_region as region
ON
location.region_geoname_id = region.region_geoname_id
JOIN
geonames_country as country
ON
region.country_geoname_id = country.country_geoname_id
WHERE
location.location_name like 'location'
ORDER BY
location.location_name, region.region_name, country.country_name
LIMIT 10;
Is there a cleaner way to do this using Django models? Or do I need to just use SQL for this one?
Thank you
Do you really need the SQL to return the concatenated field? Why not query the models in the usual way (with select_related()) and then concatenate in Python? Or if you're worried about querying more columns than you need, use values_list:
locations = Location.objects.values_list(
'location_name', 'region__region_name', 'country__country_name')
location_texts = [','.join(l) for l in locations]
You can also write raw query for this in your code like that and later on you can concatenate.
Example:
org = Organization.objects.raw('SELECT organization_id, name FROM organization where is_active=1 ORDER BY name')
Keep one thing in a raw query you have to always fetch primary key of table, it's mandatory. Here organization_id is a primary key of contact_organization table.
And it's depend on you which one is useful and simple(raw query or model query).

django/python: raw sql with multiple tables

I need to perform a raw sql on multiple tables. I then render the result set. For one table I would do:
sql = "select * from my_table"
results = my_table.objects.raw(sql)
For multiple tables I am doing:
sql = "select * from my_table, my_other_table where ...."
results = big_model.objects.raw(sql)
But, do I really need to create a table/model/class big_model, which contains all fields that I may need? I will never actually store any data in this "table".
ADDED:
I have a table my_users. I have a table my_listings. These are defined in Models.py. The table my_listings has a foreign key to my_users, indicating who created the listing.
The SQL is
"select user_name, listing_text from my_listings, my_users where my_users.id = my_listings.my_user_id".
I want this SQL to generate a result set that I can use to render my page in django.
The question is: Do I have to create a model that contains the fields user_name and listing_text? Or is there some better way that still uses raw SQL (select, from, where)? Of course, my actual queries are more complicated than this example. (The models that I define in models.py become actual tables in the database hence the use of the model/table term. Not sure how else to refer to them, sorry.) I use raw sql because I found that python table references only work with simple data models.
This works. Don't know why it didn't before :( From Dennis Baker's comment:
You do NOT need to have a model with all the fields in it, you just need the first model and fields from that. You do need to have the fields with unique names and as far as I know you should use "tablename.field as fieldname" to make sure you have all unique fields. I've done some fairly complex queries with 5+ tables this way and always tie them back to a single model. –
2 . Another solution is to use a cursor. However, a cursor has to be changed from a list of tuples to a list of dictionaries. I'm sure there are cleaner ways using iterators, but this function works. It takes a string, which is the raw sql query, and returns a list which can be rendered and used in a template.
from django.db import connection, transaction
def sql_select(sql):
cursor = connection.cursor()
cursor.execute(sql)
results = cursor.fetchall()
list = []
i = 0
for row in results:
dict = {}
field = 0
while True:
try:
dict[cursor.description[field][0]] = str(results[i][field])
field = field +1
except IndexError as e:
break
i = i + 1
list.append(dict)
return list
you do not need a model that includes the fields that you want to return from your raw sql. If you happen to have a model that actually has the fields that you want to return from your raw sql then you can map your raw sql output to this model, otherwise you can use cursors to go around models altogether.

Categories