Fetch table data from database without a model related to it - django

Im looking for a way to fetch some data to display to the user.(Run a raw sql query like)
select * from "DB-table" where Name like "%blabla%" and Year like "%2020%"
My problem is that the "DB-table" lives in my database but its already populated with important data which is not related to some model in my django-app. Its a standalone table with a lot of data.
How can i refer to that table from my views.py file?

Clearly my question was not so hard..But as im new to django and python i overcomplicated things. I managed to fetch the data i wanted using something like
with connection.cursor() as cursor:
cursor.execute("SELECT * FROM 'Nvd-data'")
res = cursor.fetchall()
print(res)
For more advanced queries i think django documentation is fine.Hope that silly question helps someone

Related

columns from django.db.models.query.QuerySet

With a raw query the columns for the SQL that will be executed can be accessed like this.
query_set = Model.objects.raw('select * from table')
query_set.columns
There is no columns attribute for django.db.models.query.QuerySet.
I'm not using raw ... I was debugging a normal query set using Q filters ... it was returning way too many records ... so I wrote code to see what the results would be with normal SQL. I'd like the see the columns and the actual SQL being called on a query set so I can diagnose what the issue is without guessing.
How do you get the columns or the SQL that will be executed from a django.db.models.query.QuerySet instance?
Ok, so based on your comment, if you want to see what django has created in terms of SQL there's an attribute you can use on the Queryset.
Once you've written your query, qs = MyModel.objects.all(), you can then inspect that by doing qs.query, which if you print that out will show you the SQL query itself.
You'll have to inspect this query to see what columns are being included.
The query object is a class called Query which I can't find mention of in the django docs, but it's source is here; https://github.com/django/django/blob/master/django/db/models/sql/query.py#L136

Bulk delete Django by ids

I writing a project using Django REST Framework, Django and Postgres as a database. I want to bulk delete in one query. So, it is possible to do without writing a query using pure SQL?
There is an example, but the count of executet query equal length of a list of ids (for example, if in delete_ids 2 ids, Django will execute 2 queries):
delete_ids = [...]
MyModel.objects.filter(id__in=delete_ids).delete()
Not possible using the filter and delete together using raw sql query.
https://docs.djangoproject.com/en/2.1/topics/db/sql/
MyModel.objects.raw('DELETE FROM my_model WHERE id IN (%s)', [','.join([list_of_ids])])
For fast deletes won't advice but you can also use
sql.DeleteQuery(MyModel).delete_qs(qs, using=qs.db)
jackotyne's answer is incorrect as a DELETE statement cannot be run with django raw. The idea behind django raw is that it returns a queryset, but DELETE won't do that.
Please read the reply to this answer.
You will need a database cursor as stated in the django documentation.
with connection.cursor() as cursor:
cursor.execute(
'DELETE FROM "appname_modelname" WHERE id IN (%s)' % ', '.join(delete_ids)
)
Of course it is better to filter with django and get a queryset and do a bulk delete with queryset.delete(), but that is not always possible depending on the data's logic.

How to join with sub-table using Django's ORM?

I've this query. Orders post records by last comment on post. This query works well with small tables. However, I've filled database with random data approximately 2M rows on comment table. Analyzed query with explain and saw that sequential scan is performed on Post table.
Post.objects.extra(select={'last_update': 'select max(c.create_date) from comment_comment c where c.post_id = post_post.id'}).order_by('-last_update')
I've rewritten same query which is faster than current one. But I could not find a way to fit the query on django's orm. How can I rewrite it? If it is possible, I want to write it not using raw query as much as possible.
Regards. Thanks for any help.
select
p.*,
t.last_update
from
post_post p
join
( select c.post_id as pid, max(c.create_date) as last_update from comment_comment c group by pid) t
on p.id = t.pid
order by t.last_update desc
limit 50;
If I make some assumptions about your Django model, it will look something like this:
posts.objects
.annotate(last_update=Max('comments__create_date'))
.order_by('-last_update')[:50]
In Django, annotate is your friend.

In Django, how to implement foreign key relations between tables in different mysql dbs

In MySQL, we can have foreign key relationships between tables in different databases. I am finding it difficult to translate this relationship on the respective Django models.
I have read in the docs that cross-db relationships are not supported, but can we override some property/function so that we can make tables be identified as DB.table rather than table?
For example, there is table table1 in DB1 that gets referenced in some table2 in DB2. Django tries (unsuccessfully) to find table1 in DB2, and raises a DatabaseError
Variable Value
charset 'latin1'
exc <class '_mysql_exceptions.ProgrammingError'>
self <MySQLdb.cursors.Cursor object at 0x2a87ed0>
args (195,)
db <weakproxy at 0x2a95208 to Connection at 0xdad0>
value ProgrammingError(1146, "Table 'DB2.table1' doesn't exist")
query 'SELECT (1) AS `a` FROM `table1` WHERE `table1`.`ndx` = 195 LIMIT 1'
Almost everything works, except the save method. A push in the right direction would help a lot!
You required Manually Selecting a Database.
Looking on the error you gave, you should do something like this:
qs = table1.objects.using('DB1 ').filter(pk=id)
# just an example
In this example we are explicitly telling Django to locate table1 in DB1.
It seems we cannot do anything to get relationships working between two tables in different mysql DBs. This is by design. Ticket 17875 has some info. We need to write code that works around this.

Bulk updating a table

I want to update a customer table with a spreadsheet from our accounting system. Unfortunately I can't just clear out the data and reload all of it, because there are a few records in the table that are not in the imported data (don't ask).
For 2000 records this is taking about 5 minutes, and I wondered if there was a better way of doing it.
for row in data:
try:
try:
customer = models.Retailer.objects.get(shared_id=row['Customer'])
except models.Retailer.DoesNotExist:
customer = models.Retailer()
customer.shared_id = row['Customer']
customer.name = row['Name 1']
customer.address01 = row['Street']
customer.address02 = row['Street 2']
customer.postcode = row['Postl Code']
customer.city = row['City']
customer.save()
except:
print formatExceptionInfo("Error with Customer ID: " + str(row['Customer']))
Look at my answer here: Django: form that updates X amount of models
The QuerySet has update() method - rest is explained in above link.
I've had some success using this bulk update snippet:
http://djangosnippets.org/snippets/446/
It's a bit outdated, but it worked on django 1.1, so I suppose you can still make it work. If you are looking for a quick way to do a one time bulk insert, this is the quickest (I'm not sure I'd trust it for regular use without seriously testing performance).
I've made a terribly crude attempt on a solution for this problem, but it's not finished yet and it doesn`t support working with django orm objects directly - yet.
http://pypi.python.org/pypi/dse/0.1.0
It`s not been properly testet and let me know if you have any suggestions on how to improve it. Using the django orm to do stuff like this is terrible.
Thomas