Using raw sql in django - mysql

What would be the equivalent raw sql for the following:
def index:
Emails.objects.create(email=request.POST['invite_email'])
I have this so far, but I can't quite get the quotations working --
cursor = connection.cursor()
cursor.execute("insert into splash_emails (id, email) values ('0','request.POST[invite_email]')")
transaction.commit_unless_managed()
What would be correct way to write this, and is this the simplest way to perform raw sql?

If you ever want to see the queries django is using you can do:
emails = Emails.objects.create(email=request.POST['invite_email'])
print emails.query
It's a bit verbose, but you'll get the gist.

I think after reading the Django cookbook chapter on Security, you'll have a good idea on how to execute raw sql AND execute it safely.

Related

Cannot use placeholders for the names of schema objects in dynamic SQL statements

I am dynamically creating mysql statements in Node JS using the mysql2 library to retrieve and store data,
I recently began getting a bug 'Can't create more than max_prepared_stmt_count statements (current value: 16382)'
After doing some digging I realised I was not using placeholders within my statements and thus cached statements were not closed, as I begun changing my code to utilise the placeholders to prevent this I also realised that you can not use placeholders for the names of schema objects.
An example of many is:
let obj = await pool.execute(select * from + config_schema + .parameters);
Firstly I am unsure if this will be contributing to my prepared statements, and secondly if there is a better way to do what I am trying to achieve.
Any help/advice is greatly apricated!
Using .query() instead of .execute resolved this issue as .execute() in this library will prepare statements.

Writing to MySQL with Python without using SQL strings

I am importing data into my Python3 environment and then writing it to a MySQL database. However, there is a lot of different data tables, and so writing out each INSERT statement isn't really pragmatic, plus some have 50+ columns.
Is there a good way to create a table in MySQL directly from a dataframe, and then send insert commands to that same table using a dataframe of the same format, without having to actually type out all the col names? I started trying to call column names and format it and concat everything as a string, but it is extremely messy.
Ideally there is a function out there to directly handle this. For example:
apiconn.request("GET", url, headers=datheaders)
#pull in some JSON data from an API
eventres = apiconn.getresponse()
eventjson = json.loads(eventres.read().decode("utf-8"))
#create a dataframe from the data
eventtable = json_normalize(eventjson)
dbconn = pymysql.connect(host='hostval',
user='userval',
passwd='passval',
db='dbval')
cursor = dbconn.cursor()
sql = sqltranslate(table = 'eventtable', fun = 'append')
#where sqlwrite() is some magic function that takes a dataframe and
#creates SQL commands that pymysql can execute.
cursor.execute(sql)
What you want is a way to abstract the generation of the SQL statements.
A library like SQLAlchemy will do a good job, including a powerful way to construct DDL, DML, and DQL statements without needing to directly write any SQL.

Knex.js Select Average and Round

I am switching an application from PHP/MYSQL to Express and am using knex to connect to the MYSQL database. In one of my queries I use a statement like such (I have shortened it for brevity.)
SELECT ROUND(AVG(Q1),2) AS Q1 FROM reviews WHERE id=? AND active='1'
I am able to use ROUND if I use knex.raw but I am wondering if there is a way to write this using query builder. Using query builder makes dealing with the output on the view side so much easier than trying to navigate the objects returned from the raw query.
Here is what I have so far in knex.
let id = req.params.id;
knex('reviews')
//Can you wrap a ROUND around the average? Or do a Round at all?
.avg('Q1 as Q1')
.where('id', '=', id)
Thanks so much!
You can use raw inside select. In this case:
knex('reviews')
.select(knex.raw('ROUND(AVG(Q1),2) AS Q1'))
Check the docs here for more examples and good practices when dealing with raw statements.

How to use the `exec_insert` method?

I am using Ruby on Rails 3.2.2 and I am running the following raw SQL:
sql = "INSERT INTO articles (`title`, `user_id`) VALUES #{inserts.join(", ")}"
ActiveRecord::Base.connection.execute(sql)
However, I would like to use the Ruby on Rails exec_insert method but there isn't good documentation about that. So, how can I use the exec_insert method so to make the same thing I stated above (maybe using something like Article.connection.exec_insert(...))?
You can use exec_query for this
ActiveRecord::Base.connection().exec_query('INSERT INTO articles(title, user_id) VALUES($1, $2)', 'someQueryName', [[nil, title], [nil, user_id]])
Please note that I have used and tested $1, $2 for Postgres only as $1,$2 is the convention used for binding prepare query in postgres.
It maybe different for MySql & other databases. For Mysql I think it should be ? instead of $1, $2 etc, it depends on how the database offers binding
Also you might have to set prepare_query: true for some. Refer -http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#exec_query
exec_insert is an internal method and probably isn't what you want here. What you have should be fine.
If you're really set on using it, and need examples, the test suite possibly the best place to find them. One example is here.

Django raw sql query

I have a this model:
class Document(models.Model):
data = models.TextField()
users = models.ManyToManyField(User)
How would you convert the following query for the model above to raw sql?
Document.objects.annotate(num_users=Count(users))
I need to switch this to raw sql because there is a bug in django when using MySql that makes annotate very slow.
But I'm not sure how to handle the many to many field in raw sql..
Document.objects.raw('SELECT ...')
The easiest way to translate your Django query to SQL is to simply look at the SQL that Django generates: How can I see the raw SQL queries Django is running?
you can get corresponding query the way mentioned below:
queryset = Document.objects.annotate(num_users=Count(users))
sql_query = queryset.query
print(sql_query)