====== Import danych z bazy MS Access ======
===== Wstęp =====
Przeniesienie danych z bazy danych Microsoft Access do aplikacji Django może być zrealizowane poprzez kilka kroków. Oto jedna z najczęściej stosowanych metod:
1. **Eksport danych z bazy Access:**
* Zainstaluj narzędzie służące do eksportu danych z bazy Access do formatu, który można łatwo zaimportować do Django. Jednym z popularnych formatów jest CSV.
2. **Przygotowanie danych:**
* Otwórz plik CSV w arkuszu kalkulacyjnym lub edytorze tekstu i przeprowadź ewentualne konieczne przekształcenia danych, takie jak dostosowanie formatu, usuwanie niepotrzebnych kolumn itp.
3. **Tworzenie modeli Django:**
* W aplikacji Django stwórz modele, które odzwierciedlają strukturę danych z bazy Access.
from django.db import models
class YourModel(models.Model):
field1 = models.CharField(max_length=100)
field2 = models.IntegerField()
# Dodaj pozostałe pola zgodnie z modelem danych z bazy Access
4. **Import danych do modeli Django:**
* Użyj polecenia ''python manage.py importdata'' (gdzie ''importdata'' to własna komenda dostosowana do Twoich potrzeb) do zaimportowania danych z pliku CSV do modeli Django.
import csv
from django.core.management.base import BaseCommand
from yourapp.models import YourModel
class Command(BaseCommand):
help = 'Import data from CSV to Django models'
def handle(self, *args, **kwargs):
with open('your_data.csv', 'r') as csvfile:
csv_reader = csv.reader(csvfile)
for row in csv_reader:
YourModel.objects.create(field1=row[0], field2=row[1])
* Skorzystaj z Django ORM (Object-Relational Mapping), aby zapisywać dane z pliku CSV do bazy danych Django.
* Można też dodać obsługę błędu:
import csv
from django.core.management.base import BaseCommand
from yourapp.models import YourModel
class Command(BaseCommand):
help = 'Import data from CSV to Django models'
def handle(self, *args, **kwargs):
with open('your_data.csv', 'r') as csvfile:
csv_reader = csv.reader(csvfile)
for row in csv_reader:
try:
YourModel.objects.create(field1=row[0], field2=row[1])
except Exception as e:
# Obsługa błędów, np. zapis do pliku lub logowanie
self.stdout.write(self.style.ERROR(f"Error creating object: {e}"))
5. **Migracje i synchronizacja bazy danych:**
* Wykonaj migracje w Django, aby utworzyć tabele na podstawie modeli.
python manage.py makemigrations
python manage.py migrate
* Upewnij się, że struktura bazy danych w Django odpowiada oczekiwanej strukturze.
6. **Testowanie i weryfikacja:**
* Przetestuj aplikację, sprawdzając, czy dane zostały poprawnie zaimportowane i czy aplikacja działa zgodnie z oczekiwaniami.
Ważne jest, aby dostosować te kroki do specyfiki Twojej bazy danych Access i modeli w Django. Ten ogólny proces jest jednak często stosowany i stanowi punkt wyjścia dla przeniesienia danych między różnymi systemami baz danych.
Plik ''your_data.csv'' w tym przypadku zawiera dane jednej tabeli bazy danych Access. Każda tabela w bazie danych Access odpowiada jednemu modelowi w Django. W pliku CSV każdy wiersz reprezentuje rekord w tabeli, a kolumny odpowiadają polom w tym rekordzie.
Przykładowo, jeśli w bazie danych Access masz tabelę o nazwie ''Customers'' z kolumnami ''CustomerID'', ''FirstName'', ''LastName'', to plik CSV może wyglądać tak:
CustomerID,FirstName,LastName
1,John,Doe
2,Jane,Smith
3,Bob,Johnson
W powyższym przykładzie, plik CSV zawiera dane jednej tabeli (''Customers''), a rekordy w tym pliku odpowiadają rekordom w tej tabeli. Kolumny w pliku CSV odpowiadają polom w modelu Django dla tej tabeli.
Aby zaimportować dane z trzech powiązanych tabel bazy danych Access do trzech modeli Django z zachowaniem relacji, musisz uwzględnić kilka kwestii:
1. **Ustalenie struktury relacji:**
* Zidentyfikuj, jakie relacje występują między tymi trzema tabelami w bazie danych Access. Na przykład, czy są to relacje jeden do wielu, wiele do wielu itp.
2. **Stworzenie modeli Django:**
* Stwórz modele Django, które odzwierciedlają strukturę tych trzech tabel i uwzględniają relacje między nimi.
from django.db import models
class Table1(models.Model):
# Pola dla tabeli 1
class Table2(models.Model):
table1 = models.ForeignKey(Table1, on_delete=models.CASCADE)
# Pola dla tabeli 2
class Table3(models.Model):
table2 = models.ForeignKey(Table2, on_delete=models.CASCADE)
# Pola dla tabeli 3
3. **Import danych:**
* Importuj dane z plików CSV do modeli, zachowując przy tym relacje między nimi. Musisz zadbać o to, aby rekordy w plikach CSV odzwierciedlały strukturę relacji między tabelami.
* Przykładowo, możesz najpierw zaimportować dane do `Table1`, a następnie użyć kluczy obcych, aby zidentyfikować relacje między `Table1`, `Table2`, i `Table3`.
# Import danych do Table1
with open('table1_data.csv', 'r') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=';')
for row in csv_reader:
Table1.objects.create(field1=row[0], field2=row[1])
# Import danych do Table2 i uwzględnienie klucza obcego do Table1
with open('table2_data.csv', 'r') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=';')
for row in csv_reader:
table1_instance = Table1.objects.get(pk=row[0])
Table2.objects.create(table1=table1_instance, field3=row[1])
# Import danych do Table3 i uwzględnienie klucza obcego do Table2
with open('table3_data.csv', 'r') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=';')
for row in csv_reader:
table2_instance = Table2.objects.get(pk=row[0])
Table3.objects.create(table2=table2_instance, field4=row[1])
W tym kodzie kluczową opcją jest dodanie argumentu ''delimiter=';' '' w funkcji csv.reader. To ustawienie informuje moduł csv, że separator pól w pliku CSV to średnik.
4. **Migracje i synchronizacja bazy danych:**
* Wykonaj migracje, aby utworzyć tabele na podstawie modeli i zdefiniowanych relacji.
python manage.py makemigrations
python manage.py migrate
5. **Testowanie i weryfikacja:**
* Przetestuj aplikację, sprawdzając, czy dane zostały poprawnie zaimportowane i czy relacje są zachowane w aplikacji Django.
Powyższy kod jest jedynie przykładem, który należy dostosować do konkretnych struktur tabel i relacji w bazie danych Access oraz do struktury plików CSV z danymi. Warto także zauważyć, że klucze obce, takie jak ''ForeignKey'', muszą być zachowane, aby relacje działały poprawnie.
W powyższych przykładach, pliki źródłowe CSV (''table1_data.csv'', ''table2_data.csv'', ''table3_data.csv'') mogą znajdować się w dowolnym katalogu na twoim systemie plików. Lokalizacja plików z danymi CSV zależy od twojej preferencji i struktury projektu.
W praktyce mogą się one znajdować na przykład:
1. **W głównym katalogu projektu Django:**
* Jeśli pliki CSV są w głównym katalogu projektu, to ścieżki w kodzie mogą wyglądać na przykład tak:
with open('table1_data.csv', 'r') as csvfile:
# ...
2. **W katalogu aplikacji Django:**
* Możesz również umieścić pliki CSV w katalogu konkretnej aplikacji Django (np. w katalogu, gdzie znajduje się plik ''models.py'' dla danej aplikacji). Wtedy ścieżki będą wyglądać na przykład tak:
with open('yourapp/table1_data.csv', 'r') as csvfile:
# ...
Pamiętaj, aby dostosować ścieżki do rzeczywistej struktury katalogów w twoim projekcie Django. Ważne jest również, aby pliki CSV były dostępne w czasie wykonywania skryptu importu. Jeżeli pliki znajdują się w innych katalogach, upewnij się, że podajesz poprawne ścieżki dostępu.
===== Przykład importu utworów do modelu Song =====
Widok modelu do którego importujemy utwory:
from django.db import models
from django.utils import timezone
from .verbose_names import verbose_names
from django.core.validators import MinValueValidator, MaxValueValidator, ValidationError
class BaseModel(models.Model):
created_at = models.DateTimeField(default=timezone.now, verbose_name=verbose_names['created_at'], editable=False)
modified_at = models.DateTimeField(auto_now=True, verbose_name='Data ostatniej modyfikacji')
class Meta:
abstract = True
class Song(BaseModel):
song_title = models.CharField(max_length=200, verbose_name=verbose_names['song_title'])
release_year = models.PositiveIntegerField(
validators=[MinValueValidator(1000),validate_release_year],verbose_name=verbose_names['release_year'])
duration = models.DurationField(null=True, verbose_name=verbose_names['duration'])
class Meta:
verbose_name = 'Song'
verbose_name_plural = 'Songs'
unique_together = ('song_title', 'release_year')
def __str__(self):
return f"{self.song_title}, ({self.release_year})"
Widok struktury przykładowego pliku CSV:
Utwór;1983;00:02:00
Złoty krążek;2003;00:08:22
Alibaba;1987;00:01:44
Złoty Liść;2004;00:02:00
Blada gwiazda;2022;00:08:22
Pusta Studnia;1999;00:01:44
Złamany patyk;1982;00:02:00
Stary Żółw;2004;00:08:22
Ślepa Furia;1988;00:01:44
Cuchnący hipopotam;2005;00:02:00
Blade Jajo;2023;00:08:22
Śmierdząca kupa;2000;00:01:44
Zryty mózg;1983;00:02:00
Maniana;2005;00:08:22
Zimny pręt;1989;00:01:44
Złamana glizda;2006;00:02:00
Zimny piach;2023;00:08:22
Blade oko;2001;00:01:44
Płonący wiatr;1984;00:02:00
Gorące Iglo;2006;00:08:22
Delikatny łomot;1990;00:01:44
Suche gacie na dnie morza;2007;00:02:00
Matowe lustro;2022;00:08:22
Głucha cisza;2002;00:01:44
Blada czerwień;1985;00:02:00
Niski drapacz chmur;2007;00:08:22
Słoneczna sztolnia;1991;00:01:44
Płytki prysznic;2008;00:02:00
Mocna herbata;2020;00:08:22
Zielona cytryna;2003;00:01:44
Polny czołg;1986;00:02:00
Powyższy plik umieszczamy w katalogu django tam gdzie znajduje się plik ''manage.py''.
W katalogu naszej aplikacji tworzymy katalogi ''managment/commands'' a w nim plik ''importdata.py''.
yourproject/
├── yourproject/
│ ├── yourapp/
│ │ ├── management/
│ │ │ └── commands/
│ │ │ ├── __init__.py
│ │ │ └── importdata.py # Plik z kodem importu CSV
│ │ ├── __init__.py
│ │ ├── models.py
│ │ └── ...
│ ├── yourproject/
│ │ ├── __init__.py
│ │ ├── settings.py
│ │ ├── urls.py
│ │ └── ...
│ └── manage.py
└── venv/
Przykładowy widok pliku ''importdata.py''.
import csv
from django.core.management.base import BaseCommand
from dbcdapp.models import Song
from datetime import timedelta
class Command(BaseCommand):
help = 'Import data from CSV to Django models'
def handle(self, *args, **kwargs):
with open('song_data.csv', newline='', encoding='utf-8') as csvfile:
csv_reader = csv.reader(csvfile, delimiter=';')
for row in csv_reader:
duration_str = row[2]
duration_parts = duration_str.split(':')
duration = timedelta(hours=int(duration_parts[0]), minutes=int(duration_parts[1]),
seconds=int(duration_parts[2]))
Song.objects.create(song_title=row[0], release_year=int(row[1]), duration=duration)
self.stdout.write(self.style.SUCCESS('Data imported successfully'))
Powyższy kod dzieli ciąg ''00:02:00'' na części (godziny, minuty, sekundy), a następnie tworzy obiekt ''timedelta''. Ten obiekt możesz następnie użyć jako trwanie utworu w twoim modelu.
Upewnij się, że kolumna ''duration'' w twoim modelu jest odpowiedniego typu, na przykład ''DurationField''. Jeśli nie masz takiego pola w modelu, możesz je dodać, aby poprawnie przechowywać trwanie utworu.
Warto też zauważyć, że plik CSV nie zawiera nagłówka kolumn. Pierwsza linia zawiera dane utworu. Natomiast do pul modelu ''(song_title=row[0], release_year=int(row[1]), duration=duration)'' przypisana jest odpowiednia kolumna pliku CSV licząc w kolejności od ''0''.
Trzeba również pamiętać, że ''dbcdapp'' w linii ''from dbcdapp.models import Song'' to nazwa naszej aplikacji. Opcje ''encoding=utf-8'' i ''delimiter=;'' określają w jakim kodowaniu jest plik CSV oraz jakim znakiem są rozdzielone pola kolumn.