Я работаю над проектом Django / React. Используя DRF
, я создаю маршрут API для выполнения SQL запросов в моей базе данных PostgreSQL
. Но у меня возникают проблемы с моей текущей настройкой кода.
Я настроил свой запрос INSERT
в API как raw queries (using cursor)
, заключенный в многострочную строку из тройных кавычек """INSERT..."""
, затем отформатировал мои значения, используя форматирование строки %s
. В моем API я записываю все данные из тела запроса в переменную. Все работает нормально, если все данные запроса заполнены. Но если это null
, Django, очевидно, присваивает None
переменной.
Теперь вернемся к моему sql запросу, Django будет обрабатывать ноль %s
как None
и как table column
вместо правильного нулевого значения, таким образом выбрасывая ProgrammingError
column "none" does not exist
.
Вот примеры кодов:
Реагировать Интерфейс
const [lastName, setLastName] = useState('')
const [firstName, setFirstName] = useState('')
const [middleName, setMiddleName] = useState('')
const [nameExtn, setNameExtn] = useState('')
const [sex, setSex] = useState('')
const [civilStatus, setCivilStatus] = useState('')
const [bloodType, setBloodType] = useState('')
const [height, setHeight] = useState('')
const [weight, setWeight] = useState('')
const newPersonalInfo = (token, data) => {
let endpoint = "/jobnet/api/profile/pds/basic/personal/"
let lookupOptions = {
method: "POST",
headers: {
'Content-Type': 'application/json',
'Authorization': `Token ${token}`
},
body: JSON.stringify(data),
credentials: 'include'
}
fetch(endpoint, lookupOptions)
.then(res=>res.json())
.then(function(info){
console.log(info)
})
.catch(err=>console.log(err));
}
const handleNewPersonalInfo = () => {
newPersonalInfo(props.user.token, {
firstname: firstName,
lastname: lastName,
middlename: middleName,
extension: nameExtn,
birthdate: selectedDate,
sex: sex,
civilstatus: civilStatus,
bloodtype: bloodType,
height: height,
weight: weight,
})
}
...
return(
<Button
variant="contained"
color="primary"
onClick={handleNewPersonalInfo}
>
SAVE
</Button>
)
Django API (DRF)
class APIListCreate__PersonalInfo(generics.ListCreateAPIView):
try:
serializer_class = PDSBasicPersonalInfoSerializer
permission_classes = (jobnet_permissions.IsAuthenticated,)
authentication_classes = (knox_TokenAuthentication,)
except Exception as e:
traceback.print_exc()
def get_queryset(self):
user = self.request.user
if user and user.is_authenticated:
query = ("""
SELECT
bsinfo.firstname,
bsinfo.middlename,
bsinfo.surname,
bsinfo.birthdate,
bsinfo.sex,
bsinfo.extention,
bsinfo.civilstatus,
bsinfo.height_m,
bsinfo.weight_kg,
bsinfo.bloodtype,
bsinfo.photo_path
FROM jobnet_app.basicinfo bsinfo
WHERE
id=%s
""" % user.id)
return raw_sql_select(query, "default")
else:
return None
def get(self, request):
data = [
{
"first_name": col.firstname,
"middle_name": col.middlename,
"last_name": col.surname,
"name_extension": col.extention,
"birthdate": col.birthdate,
"sex": col.sex,
"civil_status": col.civilstatus,
"height": col.height_m,
"weight": col.weight_kg,
"blood_type": col.bloodtype,
"photo_path": col.photo_path
} for col in self.get_queryset()[1]
]
return Response(data[0])
def post(self, request):
try:
user = request.user.id
firstname = request.data.get('firstname') or ''
middlename = request.data.get('middlename') or ''
lastname = request.data.get('lastname') or ''
birthdate = request.data.get('birthdate') or ''
sex = request.data.get('sex') or ''
extension = request.data.get('extension') or ''
civilstatus = request.data.get('civilstatus') or ''
height_m = request.data.get('height') or 0
weight_kg = request.data.get('weight') or 0
bloodtype = request.data.get('bloodtype') or ''
query = ("""
START TRANSACTION;
INSERT INTO jobnet_app.basicinfo (
id,
firstname,
middlename,
surname,
birthdate,
sex,
extention,
civilstatus,
height_m,
bloodtype,
weight_kg
)
VALUES (%s,'%s','%s','%s','%s','%s','%s','%s',%s,'%s',%s);
""" % (
user,
firstname,
middlename,
lastname,
birthdate,
sex,
extension,
civilstatus,
height_m,
bloodtype,
weight_kg
)
)
unformatted_query_result = raw_sql_insert(query, "default")
if unformatted_query_result:
raw_sql_commit("default")
return Response({
"success": True,
"message": "Your basic personal information has been updated successfully."
}, status=status.HTTP_201_CREATED)
else:
raw_sql_rollback("default")
return Response({
"success": False,
"message": "There was a problem updating your personal information."
}, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
traceback.print_exc()
return Response({
"success": False,
"message":"Internal System Error: " + str(e)
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
При указанной выше настройке я получаю такую ошибку:
Traceback (most recent call last):
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
return self.cursor.execute(sql)
psycopg2.ProgrammingError: column "none" does not exist
LINE 4: ...on','2002-03-18T06:18:45.284Z','Male','','Single',None,'B+',...
^
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "D:\PGADN\Projects\pgadn-v2-website\adnwebsite\reactify\utils.py", line 17, in raw_sql_insert
cn.execute(query)
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\backends\utils.py", line 100, in execute
return super().execute(sql, params)
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\backends\utils.py", line 68, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\Acer\Envs\adnwebsite-react\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
return self.cursor.execute(sql)
django.db.utils.ProgrammingError: column "none" does not exist
LINE 4: ...on','2002-03-18T06:18:45.284Z','Male','','Single',None,'B+',...
Я использую:
- Django 2.0.6
- Django Rest Framework 3.10.3
- PostgreSQL 11.3 (в моей разработке машина) и PostgreSQL 12.1 (на рабочем сервере) (хотя вышеуказанная ошибка еще не была реплицирована на сервер)
Примечание: raw_sql_select
, raw_sql_insert
, raw_sql_commit
, raw_sql_rollback
- это просто пользовательские вспомогательные функции, которые обрабатывают фактическое выполнение курсора в фоновом режиме.