Выполнение необработанного SQL с помощью python3/Django 1.7

Я работаю с simple_history, потому что мне нужны исторические данные моих моделей. У меня есть модель с именем po_staff, которая имеет «историческую» модель с именем pool_historicalpo_staff. Теперь я хочу получить набор запросов на основе pool_historicalpo_staff с последней записью для каждого сотрудника (старался сделать максимально просто, т.к. реальный запрос намного сложнее). В настоящее время я работаю над SQLLite

Историческая модель содержит следующие данные:

ID staff_nr valid      staff_firstname staff_lastname
1  111      01/01/2014 Firstname1      Lastname1
2  3        01/01/2014 Firstname2      Lastname2
2  3        01/04/2014 Firstname2      Lastname2_new #Employee has changed his Lastname

Этот код отлично работает (упорядоченный алфавит):

qs = po_staff.history.raw ('SELECT * FROM pool_historicalpo_staff '
     'WHERE clientID_id is %s and companyID_id is %s '
     'GROUP BY id '
     'ORDER BY staff_name, staff_surname ',
     [client_id, company_id])

Я должен использовать "id" для группировки, потому что staff_nr может быть изменен от пользователя (но это все тот же сотрудник).

ПРОБЛЕМА 1: Пользователь может выбрать порядок результата между alpabetical и staff_id

Чтобы сделать это возможным, я добавил в запрос 3-й аргумент:

if order == 1:
    order_by = "staff_name, staff_surname"
else:
    order_by = "staff_nr"
qs = po_staff.history.raw ('SELECT * FROM pool_historicalpo_staff '
     'WHERE clientID_id is %s and companyID_id is %s '
     'GROUP BY id '
     'ORDER BY %s ',
     [client_id, company_id, order_by])

Запрос работает, но вместо алфавитного порядка я получаю его по «id».

ПРОБЛЕМА 2: Запрос должен выполняться и для других моделей. Просто модель и order_by будут другими. Я не хочу писать для каждой модели почти одинаковый запрос, поэтому я попытался сделать его более гибким:

model      = ....  # instance of current model
order_by   = ....  # gets the choosen order for current model, p.e. "staff_name, staff_surname"
model_name = ....  # gets the model name, p.e. "pool_historicalpo_staff"

qs = model.history.raw ('SELECT * FROM %s '
     'WHERE clientID_id is %s and companyID_id is %s '
     'GROUP BY id '
     'ORDER BY %s ',
     [model_name, client_id, company_id, order_by])

Я получаю сообщение об ошибке при выполнении этого запроса:

Request Method:     GET
Request URL:    http://127.0.0.1:8000/framework/21/?view=kanban
Django Version:     1.7
Exception Type:     OperationalError
Exception Value:    near "?": syntax error
Exception Location:     c:\python34\lib\site-packages\django\db\backends\sqlite3\base.py in     
                        execute, line 485
Python Executable:  c:\python34\python.EXE
Python Version:     3.4.0

Надеюсь, я все понятно объяснил. Я новичок в django, это мой первый необработанный SQL.

Большое спасибо за помощь!


person sascha2014    schedule 11.01.2015    source источник


Ответы (1)


Это похоже на Django: синтаксическая ошибка MySQL при передача параметров в необработанный SQL-запрос

Краткий ответ: вы можете передавать параметры только в запрос. Для поддержки замены частей синтаксиса SQL, таких как имена таблиц, вам потребуется построить запрос в два прохода, передав в запрос фактические параметры только во втором проходе.

Надеюсь это поможет.

person bimsapi    schedule 11.01.2015
comment
спасибо бимсапи. Но как мне это сделать (извините, я новичок)? У вас есть короткий пример? Большое спасибо!! - person sascha2014; 11.01.2015
comment
В предоставленной ссылке также есть пример. В основном что-то вроде sql = 'select * from {} where foo = %s'.format(table_name), за которым следует model.history.raw(sql, params). Первый проход использует Python format для вставки имени таблицы (в котором используется заполнитель {} — см. docs.python.org/2/library/string.html#string-formatting), второй проход фактически выполняет запрос (который использует заполнитель %s). - person bimsapi; 11.01.2015
comment
Спасибо, я надеялся избежать строкового форматирования запросов, но если это единственный способ.... - person sascha2014; 11.01.2015