Spis treści

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:

2. Przygotowanie danych:

3. Tworzenie modeli Django:

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:

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])
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:

python manage.py makemigrations
python manage.py migrate

6. Testowanie i weryfikacja:

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:

2. Stworzenie modeli Django:

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:

# 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:

python manage.py makemigrations
python manage.py migrate

5. Testowanie i weryfikacja:

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:

with open('table1_data.csv', 'r') as csvfile:
    # ...

2. W katalogu aplikacji Django:

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:

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

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.