Может понадобится, например, когда нужно перенести какие то данные из одной базы данных, в базу данных под управлением django. В таком случае, по первой базе данных нет необходимости (или невозможно) формировать модели.
При необходимости, к первой базе тоже можно применить модели в django приложении.
Первым делом, добавляем второе подключение («sourcedb«), наряду с основным («default«) в файле конфигов settings.py. Для примера, у нас mysql:
Теперь можно использовать второе подключение для забора данных:
1) одну запись (fetchone):
from django.db import connections
…
def get_single_record_from_second_database(order_number):
try:
with connections['sourcedb'].cursor() as cursor:
cursor.execute("""SELECT id, `sum`, user_id
FROM orders
WHERE order_number = '%s'
""" % order_number)
order = cursor.fetchone()
cursor.close()
except Exception as error:
print("Failed to read data from Orders table (for %s):" % order_number, error)
...
2) или обрабатываем много записей (fetchall)
from django.db import connections
…
def get_multiple_records_from_second_database(date):
try:
with connections['sourcedb'].cursor() as cursor:
cursor.execute("""SELECT id, `sum`, user_id
FROM orders
WHERE date = '%s'
""" % date)
orders = cursor.fetchall()
for order in orders:
...
cursor.close()
except Exception as error:
print("Failed to read data from Orders table (for %s):" % date, error)
...
В цикле for можно обрабатывать заказы (order) и заполнять данными основную (default) базу данных
Это руководство для новичков в Django, которые прочитали начальное руководство по Django на официальном сайте и столкнулись с задачей загрузки csv файла с таблицей в базу данных
В этом случае, у вас есть приложение polls, с урлами, моделями, вьюшками для классов вопросов (Question) и ответов (Choices). И база данных с сгенерированными таблицами (polls_question, polls_choice)
Для примера, будем загружать в базу данных csv файл с вопросами (Questions).
Назовем файл questions_01a.csv и поместим туда такое содержимое:
Why?,2022-11-14 10:00
For what?,2022-11-14 10:01
When?,2022-11-14 10:02
Where?,2022-11-14 10:03
Перенос строк — как разделитель информации по вопросам, и запятая — как разделитель ячеек данных
Изменения в /polls/urls.py:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
…
path('upload_csv/', views.upload_csv, name='upload_csv'),
]
Изменения в /polls/views.py:
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.views import generic
from django.utils import timezone
from django.contrib import messages
from .models import Question, Choice
…
def upload_csv(request):
data = {}
if "GET" == request.method:
return render(request, "polls/upload.html", data)
# if not GET, then proceed
try:
csv_file = request.FILES["csv_file"]
if not csv_file.name.endswith('.csv'):
messages.error(request, 'File is not a CSV')
return HttpResponseRedirect(reverse("polls:upload_csv"))
# if file is too large - error
if csv_file.multiple_chunks():
messages.error(request, "Uploaded file is too big (%.2f MB). " % (csv_file.size/(1000*1000),))
return HttpResponseRedirect(reverse("polls:upload_csv"))
file_data = csv_file.read().decode("utf-8")
lines = file_data.split("\n")
# loop over the lines and save them to db via model
for line in lines:
fields = line.split(",")
try:
question = Question(
question_text=fields[0],
pub_date=fields[1],
)
question.save()
except Exception as e:
messages.error(request, "Unable to upload file. "+repr(e))
pass
except Exception as e:
messages.error(request, "Unable to upload file. "+repr(e))
return HttpResponseRedirect(reverse("polls:upload_csv"))
Что делаем в views.py:
Импортируем стандартный фреймворк сообщений (messages), чтобы можно было на страничке выводить ошибки
Файл будем посылать методом POST, если же запрос GET — открываем страницу аплода
Делаем простые проверки получаемого файла (тип файла и максимальный размер)
Читаем построчно и сохраняем в базу данных, через модель
Создаем страничку для загрузки файла — /polls/templates/polls/upload.html со следующим кодом: