====== 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.