Mapowanie danych przy migracji sklepu - produkty, klienci, zamówienia
Mapowanie danych to faza migracji, którą najczęściej niedoszacowuje się. „Przeniesiemy dane" brzmi prosto. W praktyce 20-40% projektu migracyjnego to mapowanie, czyszczenie i walidacja. To też najmocniejszy moment, żeby zrobić porządek - stare dane z poprzedniej platformy zawierają zwykle 10-30% rzeczy do wyrzucenia.
Spis treści (7)
W skrócie
- 1. Każdy typ danych = osobny projekt mapowania: produkty, kategorie, klienci, zamówienia, atrybuty, redirecty
- 2. Czyszczenie obowiązkowe. Stare dane mają duplikaty, niespójności, śmieci
- 3. Walidacja po migracji: sample queries, automated testy
- 4. Edge cases: stare zamówienia z innym schematem, klienci z dziwnym kodowaniem
- 5. „Łatwiej niż się wydaje" - pułapka. Zawsze trwa 2× dłużej niż estymata
Co konkretnie mapujesz
1. Produkty. Najtrudniejszy element. Każdy produkt ma:
- SKU (rzadko zmienia się)
- Nazwa, opis (lokalizacja)
- Atrybuty (kolor, rozmiar, etc.)
- Kategorie (które kategorie ten produkt jest)
- Ceny (cennik bazowy + kontraktowe per klient)
- Zdjęcia (URL'e + binary files)
- Dokumenty (PDF specyfikacje)
- Stan magazynowy
- Status (aktywny / nieaktywny / archived)
2. Kategorie. Drzewo kategorii. Stara platforma może mieć inną hierarchię. Mapowanie 1:1 rzadko działa.
3. Klienci.
- Dane podstawowe (NIP, nazwa, adres)
- Adresy dostawy (predefined)
- Hasła (NIGDY nie migruj plain text - wymuś reset)
- Cenniki kontraktowe (link do ERP)
- Limit kredytowy (link do ERP)
4. Zamówienia historyczne.
- Header (numer, data, klient, kwoty)
- Pozycje (produkty, ilości, ceny w momencie zamówienia)
- Adres dostawy (snapshot z momentu zamówienia)
- Status, dokumenty (faktury PDF)
5. CMS pages, blog posts.
- Treść + obrazy + meta tagi
6. Konfiguracje.
- Stawki podatkowe
- Strefy dostawy
- Metody płatności
- Promocje aktywne
7. Custom data. Wszystko co specyficzne dla tego sklepu - wymaga osobnego mapowania.
Source → Target mapping
Dla każdego typu danych - tabela mapowania.
Przykład: Produkt Magento 1 → Magento 2
| M1 field | M2 field | Transformacja |
|---|---|---|
entity_id |
entity_id |
Bezpośrednio |
sku |
sku |
Bezpośrednio |
name |
name |
Bezpośrednio |
description |
description |
Sanitize HTML |
short_description |
short_description |
Sanitize HTML |
price |
price |
Decimal precision check |
meta_title |
meta_title |
Bezpośrednio |
manufacturer_id |
manufacturer_id |
Lookup w mapie producentów |
attributes_* |
attributes_* |
Mapping per attribute |
category_ids |
category_ids |
Mapping z mapy kategorii |
gallery |
gallery |
Copy files do M2 storage |
Dla custom atrybutów (np. wymiary_pakowania_m1 → wymiary_pakowania_m2) - osobny mapping per atrybut.
Czyszczenie danych
Migracja to dobry moment na cleanup.
Typowe problemy w starej bazie:
1. Duplikaty produktów. Ten sam produkt ma 2 wpisy z różnymi SKU. Decyzja: zostawić oba, scalić, lub usunąć słabszy.
2. Produkty archived ale w katalogu. „Nie sprzedajemy od 2 lat, ale są w bazie". Decyzja: archive (nie migruj) lub flag inactive.
3. Klienci nieaktywni. Klient nie kupował od 5 lat. Czy migrować? Najczęściej tak (history of contract), ale flagujesz jako inactive.
4. Test orders / test customers.
Klienci z emailami test@test.com, zamówienia ze SKU TEST-001. Wyrzuć.
5. Spóźnione tłumaczenia. Produkt po polsku + częściowo po angielsku + niemiecka wersja niedokończona. Cleanup language packs.
6. Stare kategorie. „Promocje świąteczne 2018". Wyrzuć lub archive.
7. Linki do nieistniejących obrazów. Plik z bazy nie istnieje na dysku. Skanuj przed migracją.
Wyniki cleanup:
Typowy stary sklep: po cleanup -15-30% danych (mniej produktów, mniej kategorii, mniej klientów). Mniej do migracji = mniej problemów.
Walidacja po migracji
Po migration tool zakończeniu pracy - walidacja.
Sample queries:
-- Liczba produktów
SELECT COUNT(*) FROM products_m1; -- 12345
SELECT COUNT(*) FROM products_m2; -- 12345 (powinno być takie same)
-- Sample compare
SELECT m1.sku, m1.name, m2.name FROM products_m1 m1 LEFT JOIN products_m2 m2 ON m1.sku = m2.sku WHERE m1.sku IN ('SKU1', 'SKU2', 'SKU3');
-- Sprawdzenie corrupted JSON
SELECT * FROM products_m2 WHERE attributes_json NOT LIKE '{%';
Automated tests:
def test_product_count():
assert m1_count == m2_count
def test_sample_products():
for sku in sample_skus:
m1_product = m1_db.get(sku)
m2_product = m2_db.get(sku)
assert m1_product.name == m2_product.name
assert abs(m1_product.price - m2_product.price) < 0.01
Manual review:
Sample 50-100 produktów + 50-100 klientów + 50-100 zamówień. Reviewer (osoba z biznesu) sprawdza ręcznie.
Mapowanie pól nietypowych
Większość pól mapuje się 1:1. Wyzwania:
1. Custom atrybuty z innym typem.
M1: wymiary jako varchar(255). M2: chcemy 3 osobne (długość, szerokość, wysokość). Parser potrzebny.
2. Stare jednostki. M1: ceny w PLN. M2: multi-currency, każda cena ma waluty. Migracja → wszystko jako PLN, multi-currency dodajesz później.
3. Daty z różnych time zones.
Stara baza w UTC, nowa w Europe/Warsaw. Convert podczas migracji.
4. Encoding. Stara baza Windows-1250, nowa UTF-8. Convert before insert.
5. NULL vs. empty string. M1 trzyma puste opisy jako NULL, M2 jako empty string. Mapowanie eksplicytne.
Migracja zdjęć i media
Często niedoceniane. 50k produktów × 5 zdjęć × średnio 200 KB = 50 GB. Migracja:
Opcja 1: Copy files. Skrypt który czyta listę produktów + ich zdjęcia, copies do nowej lokalizacji.
rsync -av /old-storage/catalog/product/ /new-storage/catalog/product/
Opcja 2: Re-upload. Nowy sklep ma inny storage backend (np. S3). Re-upload przez API.
Opcja 3: Reference (link do starego storage). Plik zostaje w starym storage, nowy sklep odwołuje się do niego. Tymczasowe rozwiązanie.
Edge case: stary storage z niezsynchronizowanymi nazwami. „Produkt ABC ma zdjęcie produkt-abc-1.jpg" - ale na dysku jest Produkt-ABC-1.jpg (case sensitive). Renaming.
Najczęstsze problemy
1. Niedoszacowanie czasu na cleanup. „Dane są w porządku" - po analizie okazuje się że 25% to śmieci.
2. Brak walidacji. Migration tool zwrócił „Done", ale 5% danych corrupted. Bez walidacji nie zauważysz.
3. Migracja test data do prod. Test customers, test orders w prod. Potem trudno wyczyścić.
4. Hasła klientów. Niemigracja hashes bezpośrednio (różne algorithms). Wymóż reset password przy pierwszym logowaniu.
5. Stare ID-y vs. nowe. Stary klient ID 12345 → nowy ID 67890. Integracje z ERP mogą trzymać stare ID-y. Mapowanie + redirect.
6. Brak delta migration. First migration zrobiona w piątek. Klienci robią zamówienia w sobotę-poniedziałek. Sekwencyjnie potrzebna jest delta.
FAQ
Czy mogę migrować hasła klientów? Tylko jeśli oba systemy używają tego samego algorytmu (rzadko). Zazwyczaj - reset password przy pierwszym logowaniu. Klient dostaje link aktywacyjny.
Co ze starszymi zamówieniami (10+ lat)? Decyzja: archive (nie migrujesz) lub migrujesz wszystkie. Większość projektów: 5 lat w nowym sklepie, starsze w PDF archive.
Czy mogę używać dump SQL z M1 do M2? Nie. Schema baz różna. Trzeba mapping tool (Data Migration Tool dla M1 → M2) lub custom ETL.
Czy mapowanie jest one-shot? Nie. Initial migration → delta migration → final migration (w cutover). 3 razy.
Co robić z klientami testowymi?
Wyrzucić przed migracją. Lub przefiltrować w mapping (WHERE email NOT LIKE '%test%').
Co dalej
- Pillar migracji: Migracje e-commerce
- M1 → M2 (konkretna ścieżka): Magento 1 → Magento 2
- SEO migracja: SEO podczas migracji
- Cutover: Plan cutover
O autorze
Jakub Owsianka
Architekt rozwiązania w WiseB2B - silniku platform B2B. Zaczynał po stronie biznesu (własne sklepy), potem deweloper, dziś projektuje wdrożenia dla sklepów z katalogami w dziesiątkach tysięcy SKU. W ostatnich latach wdrożył AI-development w zespole i funkcjonalności oparte o AI bezpośrednio w silniku sklepu.
Czytaj dalej w temacie wydajności
Wszystkie wpisyMasz pytanie do tego artykułu?
Dodatkowy kontekst, problem z własnym wdrożeniem, druga opinia - napisz wprost. Odpowiadam osobiście w 1-2 dni robocze.