{"id":82038,"date":"2020-05-19T01:42:26","date_gmt":"2020-05-18T23:42:26","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy"},"modified":"2020-05-19T01:42:26","modified_gmt":"2020-05-18T23:42:26","slug":"pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy","title":{"rendered":"Zanurzenie w Delta Lake: egzekwowanie schematu i ewolucja","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i><b>Cze\u015b\u0107, Habr! Przedstawiam wam t\u0142umaczenie artyku\u0142u <noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/09\/24\/diving-into-delta-lake-schema-enforcement-evolution.html\">\u201eZanurzenie w Delta Lake: egzekwowanie schematu i ewolucja\u201d<\/a><\/noindex> autorzy Burak Yavuz, Brenner Heintz i Denny Lee, kt\u00f3rzy przygotowali to w przededniu rozpocz\u0119cia kursu <noindex><a rel=\"nofollow\" href=\"https:\/\/otus.pw\/J1P5\/\">Data Engineer<\/a><\/noindex> od OTUS.<\/b><\/i><\/p>\n<p><img decoding=\"async\" alt=\"Zanurzenie w Delta Lake: egzekwowanie schematu i ewolucja\" src=\"\/wp-content\/uploads\/2020\/05\/1d20921d8d4a1c1e0f8afee4fc019024.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Dane, podobnie jak nasze do\u015bwiadczenie, nieustannie si\u0119 gromadz\u0105 i rozwijaj\u0105. Aby nie pozostawa\u0107 w tyle, nasze mentalne modele \u015bwiata musz\u0105 dostosowywa\u0107 si\u0119 do nowych danych, z kt\u00f3rych niekt\u00f3re zawieraj\u0105 nowe wymiary \u2014 nowe sposoby postrzegania rzeczy, o kt\u00f3rych wcze\u015bniej nie mieli\u015bmy poj\u0119cia. Te mentalne modele niewiele r\u00f3\u017cni\u0105 si\u0119 od schemat\u00f3w tabel, kt\u00f3re okre\u015blaj\u0105, jak klasyfikujemy i przetwarzamy nowe informacje.<\/p>\n<p>Prowadzi nas to do pytania o zarz\u0105dzanie schematami. W miar\u0119 jak zmieniaj\u0105 si\u0119 zadania biznesowe i wymagania, zmienia si\u0119 r\u00f3wnie\u017c struktura twoich danych. Delta Lake u\u0142atwia wdra\u017canie nowych wymiar\u00f3w w miar\u0119 zmiany danych. U\u017cytkownicy maj\u0105 dost\u0119p do prostych semantyk do zarz\u0105dzania schematami swoich tabel. Narz\u0119dzia te obejmuj\u0105 egzekwowanie schematu (Schema Enforcement), kt\u00f3re chroni u\u017cytkownik\u00f3w przed przypadkowym zanieczyszczeniem swoich tabel b\u0142\u0119dami lub zb\u0119dnymi danymi, a tak\u017ce ewolucj\u0119 schematu (Schema Evolution), kt\u00f3ra pozwala automatycznie dodawa\u0107 nowe kolumny z cennymi danymi w odpowiednich miejscach. W tym artykule zag\u0142\u0119bimy si\u0119 w wykorzystanie tych narz\u0119dzi.<\/p>\n<h2>Zrozumienie schemat\u00f3w tabel<\/h2>\n<p>\nKa\u017cdy DataFrame w Apache Spark zawiera schemat, kt\u00f3ry okre\u015bla form\u0119 danych, tak\u0105 jak typy danych, kolumny i metadane. Przy u\u017cyciu Delta Lake schemat tabeli jest przechowywany w formacie JSON wewn\u0105trz dziennika transakcji.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Czym jest egzekwowanie schematu?<\/h2>\n<p>\nEgzekwowanie schematu (Schema Enforcement), znane r\u00f3wnie\u017c jako walidacja schematu (Schema Validation), jest mechanizmem ochronnym w Delta Lake, kt\u00f3ry zapewnia jako\u015b\u0107 danych, odrzucaj\u0105c rekordy, kt\u00f3re nie pasuj\u0105 do schematu tabeli. Podobnie jak hostess w popularnej restauracji, kt\u00f3ra przyjmuje tylko rezerwacje, sprawdza, czy ka\u017cda kolumna danych wprowadzanych do tabeli znajduje si\u0119 na li\u015bcie oczekiwanych kolumn (innymi s\u0142owy, czy dla ka\u017cdej z nich istnieje \u201erezerwacja\u201d), i odrzuca wszelkie rekordy z kolumnami, kt\u00f3rych nie ma na li\u015bcie.<\/p>\n<h2>Jak dzia\u0142a egzekwowanie schematu?<\/h2>\n<p>\nDelta Lake stosuje weryfikacj\u0119 schematu podczas zapisu, co oznacza, \u017ce wszystkie nowe zapisy do tabeli s\u0105 sprawdzane pod k\u0105tem zgodno\u015bci z schematem docelowej tabeli w momencie zapisu. Je\u015bli schemat jest niezgodny, Delta Lake ca\u0142kowicie anuluje transakcj\u0119 (dane nie s\u0105 zapisywane) i generuje wyj\u0105tek, aby powiadomi\u0107 u\u017cytkownika o niezgodno\u015bci.<br \/>\nAby okre\u015bli\u0107 zgodno\u015b\u0107 zapisu, Delta Lake stosuje nast\u0119puj\u0105ce zasady. Zapisywany DataFrame:<\/p>\n<ul>\n<li>nie mo\u017ce zawiera\u0107 dodatkowych kolumn, kt\u00f3rych nie ma w schemacie docelowej tabeli. Z drugiej strony, wszystko jest w porz\u0105dku, je\u015bli dane wej\u015bciowe nie zawieraj\u0105 wszystkich kolumn z tabeli \u2014 tym kolumnom po prostu zostan\u0105 przypisane warto\u015bci null.<\/li>\n<li>nie mo\u017ce mie\u0107 typ\u00f3w danych kolumn, kt\u00f3re r\u00f3\u017cni\u0105 si\u0119 od typ\u00f3w danych kolumn w docelowej tabeli. Je\u015bli kolumna w docelowej tabeli zawiera dane typu StringType, ale odpowiadaj\u0105ca jej kolumna w DataFrame zawiera dane typu IntegerType, wymuszenie schematu spowoduje wyj\u0105tek i uniemo\u017cliwi wykonanie operacji zapisu.<\/li>\n<li>nie mo\u017ce zawiera\u0107 nazw kolumn, kt\u00f3re r\u00f3\u017cni\u0105 si\u0119 tylko wielko\u015bci\u0105 liter. Oznacza to, \u017ce nie mo\u017cesz mie\u0107 kolumn o nazwach \u2018Foo\u2019 i \u2018foo\u2019 zdefiniowanych w jednej tabeli. Chocia\u017c Spark mo\u017ce dzia\u0142a\u0107 w trybie czu\u0142ym lub nieczu\u0142ym na wielko\u015b\u0107 liter (domy\u015blnie w trybie nieczu\u0142ym), Delta Lake zachowuje wielko\u015b\u0107 liter, ale jest nieczu\u0142y w kontek\u015bcie przechowywania schematu. Parquet jest czu\u0142y na wielko\u015b\u0107 liter podczas przechowywania i zwracania informacji kolumny. Aby unikn\u0105\u0107 potencjalnych b\u0142\u0119d\u00f3w, uszkodzenia danych lub ich utraty (z czym osobi\u015bcie zetkn\u0119li\u015bmy si\u0119 w Databricks), zdecydowali\u015bmy si\u0119 doda\u0107 to ograniczenie.<\/li>\n<\/ul>\n<p>\nAby to zilustrowa\u0107, sp\u00f3jrzmy na to, co dzieje si\u0119 w poni\u017cszym kodzie podczas pr\u00f3by dodania kilku nowo wygenerowanych kolumn do tabeli Delta Lake, kt\u00f3ra nie jest jeszcze skonfigurowana do ich przyj\u0119cia.<\/p>\n<pre><code class=\"apache\"># \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c DataFrame \u0441\u0441\u0443\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0448\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 Delta Lake\nloans = sql(&quot;&quot;&quot;\n            SELECT addr_state, CAST(rand(10)*count as bigint) AS count,\n            CAST(rand(10) * 10000 * count AS double) AS amount\n            FROM loan_by_state_delta\n            &quot;&quot;&quot;)\n\n# \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0441\u0445\u0435\u043c\u0443 DataFrame\noriginal_loans.printSchema()\n\nroot\n  |-- addr_state: string (nullable = true)\n  |-- count: integer (nullable = true)\n \n# \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u043d\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443 DataFrame\nloans.printSchema()\n \nroot\n  |-- addr_state: string (nullable = true)\n  |-- count: integer (nullable = true)\n  |-- amount: double (nullable = true) # new column\n \n# \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 DataFrame (\u0441 \u043d\u043e\u0432\u044b\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u043c) \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443\nloans.write.format(&quot;delta&quot;) \n           .mode(&quot;append&quot;) \n           .save(DELTALAKE_PATH)\n\nReturns:\n\nA schema mismatch detected when writing to the Delta table.\n \nTo enable schema migration, please set:\n'.option(&quot;mergeSchema&quot;, &quot;true&quot;)'\n \nTable schema:\nroot\n-- addr_state: string (nullable = true)\n-- count: long (nullable = true)\n \nData schema:\nroot\n-- addr_state: string (nullable = true)\n-- count: long (nullable = true)\n-- amount: double (nullable = true)\n \nIf Table ACLs are enabled, these options will be ignored. Please use the ALTER TABLE command for changing the schema.<\/code><\/pre>\n<p>\nZamiast automatycznie dodawa\u0107 nowe kolumny, Delta Lake narzuca schemat i zatrzymuje zapis. Aby pom\u00f3c okre\u015bli\u0107, kt\u00f3ra kolumna (lub wiele z nich) jest przyczyn\u0105 niezgodno\u015bci, Spark wypisuje oba schematy z stosu wywo\u0142a\u0144 do por\u00f3wnania.<\/p>\n<h2>Jakie s\u0105 korzy\u015bci z wymuszania schematu?<\/h2>\n<p>\nPoniewa\u017c wymuszona aplikacja schematu stanowi do\u015b\u0107 \u015bcis\u0142\u0105 kontrol\u0119, jest doskona\u0142ym narz\u0119dziem do wykorzystania jako bramka czystego, w pe\u0142ni przekszta\u0142conego zbioru danych, gotowego do produkcji lub konsumpcji. Zazwyczaj stosuje si\u0119 j\u0105 do tabel, kt\u00f3re bezpo\u015brednio dostarczaj\u0105 dane:<\/p>\n<ul>\n<li>Algorytmy uczenia maszynowego<\/li>\n<li>Dashbordy BI<\/li>\n<li>Analiza danych i narz\u0119dzia wizualizacji<\/li>\n<li>Jakiejkolwiek systemie produkcyjnym, kt\u00f3ry wymaga \u015bci\u015ble ustrukturyzowanych, \u015bci\u015ble typowanych schemat\u00f3w semantycznych.<\/li>\n<\/ul>\n<p>\nAby przygotowa\u0107 swoje dane do tego ostatecznego bariery, wielu u\u017cytkownik\u00f3w korzysta z prostej architektury \u201emulti-hop\u201d, kt\u00f3ra stopniowo wprowadza struktur\u0119 do ich tabel. Aby dowiedzie\u0107 si\u0119 wi\u0119cej na ten temat, mo\u017cna zapozna\u0107 si\u0119 z artyku\u0142em <noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/08\/14\/productionizing-machine-learning-with-delta-lake.html\">Uczenie maszynowe na poziomie produkcyjnym z Delta Lake.<\/a><\/noindex><\/p>\n<p>Oczywi\u015bcie wymuszona aplikacja schematu mo\u017ce by\u0107 u\u017cywana w dowolnym miejscu Twojego pipeline'u, ale pami\u0119taj, \u017ce strumieniowe zapisywanie do tabeli w takim przypadku mo\u017ce by\u0107 frustruj\u0105ce, poniewa\u017c na przyk\u0142ad zapomnia\u0142e\u015b, \u017ce doda\u0142e\u015b dodatkow\u0105 kolumn\u0119 do danych wej\u015bciowych.<\/p>\n<h2>Zapobieganie rozcie\u0144czaniu danych<\/h2>\n<p>\nNa tym etapie mo\u017cesz zada\u0107 sobie pytanie, sk\u0105d ten ca\u0142y rozg\u0142os? W ko\u0144cu czasami nieoczekiwany b\u0142\u0105d \u201eniezgodno\u015bci schematu\u201d mo\u017ce podstawi\u0107 Ci nog\u0119 w Twoim przep\u0142ywie pracy, zw\u0142aszcza je\u015bli jeste\u015b nowicjuszem w Delta Lake. Dlaczego po prostu nie pozwoli\u0107 schematowi zmienia\u0107 si\u0119 w spos\u00f3b, w jaki musz\u0119 zapisa\u0107 sw\u00f3j DataFrame, niezale\u017cnie od wszystkiego?<\/p>\n<p>Jak m\u00f3wi stare przys\u0142owie, \u201euncja zapobiegania jest warta funta leczenia\u201d. W pewnym momencie, je\u015bli nie zadbasz o zastosowanie swojego schematu, nieprzyjemne problemy zwi\u0105zane z kompatybilno\u015bci\u0105 typ\u00f3w danych wyjd\u0105 na jaw \u2014 na pierwszy rzut oka jednorodne \u017ar\u00f3d\u0142a surowych danych mog\u0105 zawiera\u0107 przypadki brzegowe, uszkodzone kolumny, \u017ale sformu\u0142owane mapowania lub inne straszne rzeczy, kt\u00f3re \u015bni\u0105 si\u0119 w koszmarach. Najlepszym podej\u015bciem jest powstrzymanie tych wrog\u00f3w u bram \u2014 za pomoc\u0105 wymuszonej aplikacji schematu \u2014 i zaj\u0119cie si\u0119 nimi w \u015bwietle dziennym, a nie p\u00f3\u017aniej, gdy zaczn\u0105 w\u0119szy\u0107 w ciemnych zakamarkach Twojego kodu roboczego.<\/p>\n<p>Wymuszone stosowanie schematu zapewnia pewno\u015b\u0107, \u017ce schemat Twojej tabeli nie zmieni si\u0119, chyba \u017ce sam potwierdzisz wariant zmiany. Zapobiega to 'rozcie\u0144czeniu' danych, kt\u00f3re mo\u017ce wyst\u0105pi\u0107, gdy nowe kolumny s\u0105 dodawane tak cz\u0119sto, \u017ce wcze\u015bniej cenne, skompresowane tabele trac\u0105 swoj\u0105 warto\u015b\u0107 i u\u017cyteczno\u015b\u0107 z powodu zalania danymi. Zach\u0119caj\u0105c Ci\u0119 do bycia zamierzonym, ustalania wysokich standard\u00f3w i oczekiwania wysokiej jako\u015bci, wymuszone stosowanie schematu spe\u0142nia dok\u0142adnie to, do czego zosta\u0142o zaprojektowane \u2014 pomaga Ci pozosta\u0107 rzetelnym, a Twoim tabelom \u2014 czystymi.<\/p>\n<p>Je\u015bli przy dalszym rozwa\u017caniu zdecydujesz, \u017ce w rzeczywisto\u015bci <i>trzeba<\/i> chcesz doda\u0107 now\u0105 kolumn\u0119 \u2014 nie ma problemu, poni\u017cej znajduje si\u0119 jednolinijkowe rozwi\u0105zanie. Rozwi\u0105zanie \u2014 ewolucja schematu!<\/p>\n<h2>Czym jest ewolucja schematu?<\/h2>\n<p>\nEwolucja schematu to funkcja, kt\u00f3ra pozwala u\u017cytkownikom \u0142atwo zmienia\u0107 aktualny schemat tabeli w odpowiedzi na zmieniaj\u0105ce si\u0119 dane w czasie. Najcz\u0119\u015bciej jest u\u017cywana podczas wykonywania operacji dodawania lub zapisania, aby automatycznie dostosowa\u0107 schemat do uwzgl\u0119dnienia jednej lub kilku nowych kolumn.<\/p>\n<h2>Jak dzia\u0142a ewolucja schematu?<\/h2>\n<p>\nPod\u0105\u017caj\u0105c za przyk\u0142adem z poprzedniej sekcji, programi\u015bci mog\u0105 \u0142atwo u\u017cywa\u0107 ewolucji schematu do dodawania nowych kolumn, kt\u00f3re wcze\u015bniej zosta\u0142y odrzucone z powodu niezgodno\u015bci ze schematem. Ewolucja schematu jest aktywowana przez dodanie <code>.option('mergeSchema', 'true')<\/code> do Twojej komendy Spark <code>.write lub .writeStream.<\/code><\/p>\n<pre><code class=\"apache\"># \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 mergeSchema\nloans.write.format(&quot;delta&quot;) \n           .option(&quot;mergeSchema&quot;, &quot;true&quot;) \n           .mode(&quot;append&quot;) \n           .save(DELTALAKE_SILVER_PATH)<\/code><\/pre>\n<p>\nAby zobaczy\u0107 wykres, wykonaj nast\u0119puj\u0105ce zapytanie Spark SQL<\/p>\n<pre><code class=\"apache\"># \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0433\u0440\u0430\u0444\u0438\u043a \u0441 \u043d\u043e\u0432\u044b\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\n%sql\nSELECT addr_state, sum(`amount`) AS amount\nFROM loan_by_state_delta\nGROUP BY addr_state\nORDER BY sum(`amount`)\nDESC LIMIT 10<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Zanurzenie w Delta Lake: egzekwowanie schematu i ewolucja\" src=\"\/wp-content\/uploads\/2020\/05\/873ce67da00f69696d5b9328bd90793a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nAlternatywnie mo\u017cesz ustawi\u0107 t\u0119 opcj\u0119 dla ca\u0142ej sesji Spark, dodaj\u0105c <code>spark.databricks.delta.schema.autoMerge = True<\/code> do konfiguracji Spark. U\u017cywaj jej jednak ostro\u017cnie, poniewa\u017c wymuszone stosowanie schematu nie b\u0119dzie ju\u017c ostrzega\u0107 Ci\u0119 o niezamierzonych niezgodno\u015bciach ze schematem.<\/p>\n<p>W\u0142\u0105czaj\u0105c do zapytania parametr <code>mergeSchema<\/code>, wszystkie kolumny, kt\u00f3re s\u0105 obecne w DataFrame, ale brakuj\u0105 w docelowej tabeli, zostan\u0105 automatycznie dodane na ko\u0144cu schematu w ramach transakcji zapisu. Mog\u0105 by\u0107 tak\u017ce dodawane zagnie\u017cd\u017cone pola, kt\u00f3re r\u00f3wnie\u017c zostan\u0105 dodane na ko\u0144cu odpowiednich kolumn struktury.<\/p>\n<p>In\u017cynierowie i naukowcy mog\u0105 korzysta\u0107 z tej opcji, aby doda\u0107 nowe kolumny (np. ostatnio monitorowan\u0105 metryk\u0119 lub kolumn\u0119 wska\u017anik\u00f3w sprzeda\u017cy w tym miesi\u0105cu) do swoich istniej\u0105cych tabel produkcyjnych dla uczenia maszynowego, nie naruszaj\u0105c istniej\u0105cych modeli opartych na starych kolumnach. <\/p>\n<p>Nast\u0119puj\u0105ce typy zmian schematu s\u0105 dozwolone w ramach ewolucji schematu podczas dodawania lub nadpisywania tabeli:<\/p>\n<ul>\n<li>Dodawanie nowych kolumn (to najcz\u0119stszy scenariusz)<\/li>\n<li>Zmiana typ\u00f3w danych z NullType -&gt; jakikolwiek inny typ lub podnoszenie z ByteType -&gt; ShortType -&gt; IntegerType<\/li>\n<\/ul>\n<p>\nInne zmiany, niedozwolone w ramach ewolucji schematu, wymagaj\u0105, aby schema i dane by\u0142y nadpisane poprzez dodanie <code>.option(&quot;overwriteSchema&quot;, &quot;true&quot;)<\/code>. Na przyk\u0142ad, w przypadku, gdy kolumna \u201eFoo\u201d pocz\u0105tkowo by\u0142a typu integer, a nowa schema mia\u0142aby typ danych string, wszystkie pliki Parquet (dane) musia\u0142yby by\u0107 nadpisane. Do takich zmian nale\u017c\u0105:<\/p>\n<ul>\n<li>usuni\u0119cie kolumny<\/li>\n<li>zmiana typu danych istniej\u0105cej kolumny (na miejscu)<\/li>\n<li>zmiana nazw kolumn, kt\u00f3re r\u00f3\u017cni\u0105 si\u0119 tylko wielko\u015bci\u0105 liter (np. \u201eFoo\u201d i \u201efoo\u201d)<\/li>\n<\/ul>\n<p>\nNa koniec, w nast\u0119pnej wersji Spark 3.0 b\u0119dzie w pe\u0142ni wspierane jawne DDL (przy u\u017cyciu ALTER TABLE), co umo\u017cliwi u\u017cytkownikom wykonywanie nast\u0119puj\u0105cych dzia\u0142a\u0144 na schematach tabel:<\/p>\n<ul>\n<li>dodawanie kolumn<\/li>\n<li>zmiana komentarzy do kolumn<\/li>\n<li>konfigurowanie w\u0142a\u015bciwo\u015bci tabeli, definiuj\u0105cych zachowanie tabeli, na przyk\u0142ad ustawienie d\u0142ugo\u015bci przechowywania dziennika transakcji.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Jakie s\u0105 korzy\u015bci z ewolucji schematu?<\/h2>\n<p>\nEwolucj\u0119 schematu mo\u017cna stosowa\u0107 zawsze, gdy <i>zamierzasz<\/i> zmieni\u0107 schemat swojej tabeli (w przeciwie\u0144stwie do sytuacji, w kt\u00f3rych przypadkowo doda\u0142e\u015b kolumny do swojego DataFrame, kt\u00f3rych tam nie powinno by\u0107). To najprostszy spos\u00f3b na migracj\u0119 swojej schemy, poniewa\u017c automatycznie dodaje odpowiednie nazwy kolumn i typy danych bez konieczno\u015bci ich jawnego deklarowania.<\/p>\n<h2>Podsumowanie<\/h2>\n<p>\nWymuszone zastosowanie schematu odrzuca wszelkie nowe kolumny lub inne zmiany schematu, kt\u00f3re nie s\u0105 zgodne z Twoj\u0105 tabel\u0105. Ustanawiaj\u0105c i utrzymuj\u0105c te wysokie standardy, analitycy i in\u017cynierowie mog\u0105 polega\u0107 na tym, \u017ce ich dane maj\u0105 najwy\u017cszy poziom integralno\u015bci, co pozwala im podejmowa\u0107 bardziej efektywne decyzje biznesowe.<\/p>\n<p>Z drugiej strony, ewolucja schematu uzupe\u0142nia wymuszone zastosowanie, upraszczaj\u0105c <i>domniemane<\/i> automatyczne zmiany schematu. W ko\u0144cu nie powinno to by\u0107 skomplikowane \u2014 doda\u0107 kolumn\u0119.<\/p>\n<p>Wymuszone zastosowanie schematu to yin, podczas gdy ewolucja schematu to yang. Wsp\u00f3lnie te funkcje jak nigdy dot\u0105d uproszczaj\u0105 t\u0142umienie szum\u00f3w i dostosowanie sygna\u0142u.<\/p>\n<p><i>Chcieliby\u015bmy r\u00f3wnie\u017c podzi\u0119kowa\u0107 Mukulowi Murti i Pranavowi Anandowi za ich wk\u0142ad w ten artyku\u0142.<\/i><\/p>\n<p>Inne artyku\u0142y z tej serii:<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/08\/21\/diving-into-delta-lake-unpacking-the-transaction-log.html\">Zanurzenie w Delta Lake: rozpakowanie dziennika transakcji<\/a><\/noindex><\/p>\n<p><center><div class=\"youtube-placeholder\" data-id=\"tjb10n5wVs8\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/tjb10n5wVs8\/hqdefault.jpg\" alt=\"Odtwarzaj wideo\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<h2>Artyku\u0142y tematyczne<\/h2>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/08\/14\/productionizing-machine-learning-with-delta-lake.html\">Uczenie maszynowe na poziomie produkcyjnym z Delta Lake<\/a><\/noindex><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/discover\/data-lakes\/introduction\">Czym jest jezioro danych?<\/a><\/noindex><\/p>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/otus.pw\/J1P5\/\">Dowiedz si\u0119 wi\u0119cej o kursie<\/a><\/noindex><\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/otus\/blog\/502324\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0438 \u00abDiving Into Delta Lake: Schema Enforcement &amp; Evolution\u00bb \u0430\u0432\u0442\u043e\u0440\u043e\u0432 Burak Yavuz, Brenner Heintz and Denny Lee, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d \u0432 \u043f\u0440\u0435\u0434\u0434\u0432\u0435\u0440\u0438\u0438 \u0441\u0442\u0430\u0440\u0442\u0430 \u043a\u0443\u0440\u0441\u0430 \u00abData Engineer\u00bb \u043e\u0442 OTUS. \u0414\u0430\u043d\u043d\u044b\u0435, \u043a\u0430\u043a \u0438 \u043d\u0430\u0448 \u043e\u043f\u044b\u0442, \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0438 \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u044e\u0442\u0441\u044f. \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u043e\u0442\u0441\u0442\u0430\u0432\u0430\u0442\u044c, \u043d\u0430\u0448\u0438 \u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 \u043c\u0438\u0440\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u043e\u0432\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":82039,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-82038","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0432 Delta Lake: \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u044f \u0441\u0445\u0435\u043c\u044b | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-18T23:42:26+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-18T23:42:26+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Zanurzenie w Delta Lake: wymuszone zastosowanie i ewolucja schematu | ProHoster","description":"Cze\u015b\u0107, Habr!","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0432 Delta Lake: \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0438 \u044d\u0432\u043e\u043b\u044e\u0446\u0438\u044f \u0441\u0445\u0435\u043c\u044b | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440!","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-18T23:42:26+00:00","article:modified_time":"2020-05-18T23:42:26+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"82038","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:45:28","updated":"2022-09-29 13:43:45","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/82038","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=82038"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/82038\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/82039"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=82038"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=82038"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=82038"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}