{"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\/pt\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy","title":{"rendered":"Imers\u00e3o no Delta Lake: aplica\u00e7\u00e3o obrigat\u00f3ria e evolu\u00e7\u00e3o do esquema","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i><b>Ol\u00e1, Habr! Apresento a voc\u00eas a tradu\u00e7\u00e3o do artigo <noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/09\/24\/diving-into-delta-lake-schema-enforcement-evolution.html\">\u00abMergulhando no Delta Lake: Aplica\u00e7\u00e3o e Evolu\u00e7\u00e3o de Esquemas\u00bb<\/a><\/noindex> autores Burak Yavuz, Brenner Heintz e Denny Lee, que foi preparado antes do in\u00edcio do curso <noindex><a rel=\"nofollow\" href=\"https:\/\/otus.pw\/J1P5\/\">\u00abEngenheiro de Dados\u00bb<\/a><\/noindex> da OTUS.<\/b><\/i><\/p>\n<p><img decoding=\"async\" alt=\"Imers\u00e3o no Delta Lake: aplica\u00e7\u00e3o obrigat\u00f3ria e evolu\u00e7\u00e3o do esquema\" src=\"\/wp-content\/uploads\/2020\/05\/1d20921d8d4a1c1e0f8afee4fc019024.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Os dados, assim como nossa experi\u00eancia, est\u00e3o sempre se acumulando e evoluindo. Para n\u00e3o ficarmos para tr\u00e1s, nossos modelos mentais do mundo precisam se adaptar a novos dados, alguns dos quais cont\u00eam novas dimens\u00f5es \u2014 novas maneiras de observar coisas que antes n\u00e3o t\u00ednhamos ideia. Esses modelos mentais s\u00e3o pouco diferentes dos esquemas de tabelas que definem como classificamos e processamos novas informa\u00e7\u00f5es.<\/p>\n<p>Isso nos leva \u00e0 quest\u00e3o da gest\u00e3o de esquemas. \u00c0 medida que as necessidades e requisitos de neg\u00f3cios mudam ao longo do tempo, a estrutura de seus dados tamb\u00e9m muda. O Delta Lake permite a implementa\u00e7\u00e3o f\u00e1cil de novas dimens\u00f5es ao modificar dados. Os usu\u00e1rios t\u00eam acesso a uma sem\u00e2ntica simples para gerenciar os esquemas de suas tabelas. Essas ferramentas incluem a aplica\u00e7\u00e3o for\u00e7ada de esquemas (Schema Enforcement), que protege os usu\u00e1rios contra contamina\u00e7\u00f5es acidentais de suas tabelas por erros ou dados indesejados, bem como a evolu\u00e7\u00e3o de esquemas (Schema Evolution), que permite adicionar automaticamente novas colunas com dados valiosos nos locais apropriados. Neste artigo, vamos nos aprofundar no uso dessas ferramentas.<\/p>\n<h2>Entendendo os esquemas de tabelas<\/h2>\n<p>\nCada DataFrame no Apache Spark cont\u00e9m um esquema que define a forma dos dados, como tipos de dados, colunas e metadados. Com o Delta Lake, o esquema da tabela \u00e9 salvo no formato JSON dentro do log de transa\u00e7\u00f5es.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>O que \u00e9 a aplica\u00e7\u00e3o for\u00e7ada de esquemas?<\/h2>\n<p>\nA aplica\u00e7\u00e3o for\u00e7ada de esquemas (Schema Enforcement), tamb\u00e9m conhecida como verifica\u00e7\u00e3o de esquemas (Schema Validation), \u00e9 um mecanismo de prote\u00e7\u00e3o no Delta Lake que garante a qualidade dos dados, rejeitando registros que n\u00e3o atendem ao esquema da tabela. Assim como uma anfitri\u00e3 na recep\u00e7\u00e3o de um restaurante popular que aceita apenas reservas, ele verifica se cada coluna de dados inserida na tabela est\u00e1 na lista correta de colunas esperadas (em outras palavras, se h\u00e1 uma 'reserva' para cada uma delas) e rejeita qualquer registro com colunas que n\u00e3o est\u00e3o na lista.<\/p>\n<h2>Como funciona a aplica\u00e7\u00e3o for\u00e7ada de esquemas?<\/h2>\n<p>\nO Delta Lake utiliza verifica\u00e7\u00e3o de schema ao gravar, o que significa que todas as novas grava\u00e7\u00f5es na tabela s\u00e3o verificadas quanto \u00e0 compatibilidade com o schema da tabela de destino durante a grava\u00e7\u00e3o. Se o schema n\u00e3o for compat\u00edvel, o Delta Lake reverte completamente a transa\u00e7\u00e3o (os dados n\u00e3o s\u00e3o gravados) e gera uma exce\u00e7\u00e3o para informar o usu\u00e1rio sobre a inconsist\u00eancia.<br \/>\nPara determinar a compatibilidade da grava\u00e7\u00e3o, o Delta Lake utiliza as seguintes regras. DataFrame a ser gravado:<\/p>\n<ul>\n<li>n\u00e3o pode conter colunas adicionais que n\u00e3o est\u00e3o no schema da tabela de destino. E, vice-versa, est\u00e1 tudo certo se os dados de entrada n\u00e3o contiverem todas as colunas da tabela \u2014 essas colunas simplesmente receber\u00e3o valores nulos.<\/li>\n<li>n\u00e3o pode ter tipos de dados das colunas que sejam diferentes dos tipos de dados das colunas na tabela de destino. Se uma coluna da tabela de destino cont\u00e9m dados do tipo StringType, mas a coluna correspondente no DataFrame cont\u00e9m dados do tipo IntegerType, a aplica\u00e7\u00e3o for\u00e7ada do schema gerar\u00e1 uma exce\u00e7\u00e3o e impedir\u00e1 a execu\u00e7\u00e3o da opera\u00e7\u00e3o de grava\u00e7\u00e3o.<\/li>\n<li>n\u00e3o pode conter nomes de colunas que diferem apenas em mai\u00fasculas e min\u00fasculas. Isso significa que voc\u00ea n\u00e3o pode ter colunas com os nomes &#8216;Foo&#8217; e &#8216;foo&#8217; definidas na mesma tabela. Embora o Spark possa ser usado em modo sens\u00edvel ou insens\u00edvel (por padr\u00e3o) a mai\u00fasculas e min\u00fasculas, o Delta Lake preserva a capitaliza\u00e7\u00e3o, mas \u00e9 insens\u00edvel no armazenamento do esquema. Parquet \u00e9 sens\u00edvel a mai\u00fasculas e min\u00fasculas ao armazenar e retornar informa\u00e7\u00f5es das colunas. Para evitar poss\u00edveis erros, corrup\u00e7\u00e3o de dados ou perda de dados (com os quais j\u00e1 lidamos pessoalmente no Databricks), decidimos adicionar essa restri\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>\nPara ilustrar isso, vamos dar uma olhada no que acontece no c\u00f3digo abaixo ao tentar adicionar algumas colunas rec\u00e9m-geradas em uma tabela Delta Lake que ainda n\u00e3o est\u00e1 configurada para aceit\u00e1-las.<\/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>\nEm vez de adicionar automaticamente novas colunas, o Delta Lake imp\u00f5e o schema e interrompe a grava\u00e7\u00e3o. Para ajudar a identificar qual coluna (ou quais) \u00e9 a causa da inconsist\u00eancia, o Spark emite ambos os schemas do stack trace para compara\u00e7\u00e3o.<\/p>\n<h2>Qual \u00e9 a vantagem da aplica\u00e7\u00e3o for\u00e7ada do schema?<\/h2>\n<p>\nComo a aplica\u00e7\u00e3o for\u00e7ada de esquemas \u00e9 uma verifica\u00e7\u00e3o bastante rigorosa, \u00e9 uma excelente ferramenta para ser usada como um guardi\u00e3o de um conjunto de dados limpos e totalmente transformados, prontos para produ\u00e7\u00e3o ou consumo. Geralmente, \u00e9 aplicado a tabelas que fornecem dados diretamente:<\/p>\n<ul>\n<li>Algoritmos de aprendizado de m\u00e1quina<\/li>\n<li>Pain\u00e9is de BI<\/li>\n<li>An\u00e1lise de dados e ferramentas de visualiza\u00e7\u00e3o<\/li>\n<li>Qualquer sistema de produ\u00e7\u00e3o que exija esquemas sem\u00e2nticos rigorosamente estruturados e tipados.<\/li>\n<\/ul>\n<p>\nPara preparar seus dados para essa barreira final, muitos usu\u00e1rios utilizam uma arquitetura simples de \"multi-hop\" que gradualmente imp\u00f5e estrutura \u00e0s suas tabelas. Para saber mais sobre isso, voc\u00ea pode conferir o artigo <noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/08\/14\/productionizing-machine-learning-with-delta-lake.html\">Aprendizado de m\u00e1quina em n\u00edvel de produ\u00e7\u00e3o com Delta Lake.<\/a><\/noindex><\/p>\n<p>Claro, a aplica\u00e7\u00e3o for\u00e7ada de esquemas pode ser utilizada em qualquer lugar do seu pipeline, mas lembre-se de que a grava\u00e7\u00e3o em fluxo em uma tabela pode ser frustrante, especialmente se voc\u00ea esquecer que adicionou uma nova coluna aos dados de entrada.<\/p>\n<h2>Preven\u00e7\u00e3o de desagrega\u00e7\u00e3o de dados<\/h2>\n<p>\nNesse ponto, voc\u00ea pode se perguntar por que todo esse alvoro\u00e7o? Afinal, \u00e0s vezes, um erro inesperado de \"incompatibilidade de esquema\" pode atrapalhar seu fluxo de trabalho, especialmente se voc\u00ea \u00e9 novo no Delta Lake. Por que simplesmente n\u00e3o permitir que o esquema mude como necess\u00e1rio para que eu possa gravar meu DataFrame, custe o que custar?<\/p>\n<p>Como diz o velho ditado, \"uma on\u00e7a de preven\u00e7\u00e3o vale uma libra de rem\u00e9dio\". Em algum momento, se voc\u00ea n\u00e3o tomar cuidado com a aplica\u00e7\u00e3o do seu esquema, problemas de compatibilidade de tipos de dados surgir\u00e3o \u2014 fontes de dados brutos aparentemente homog\u00eaneas podem conter casos limites, colunas corrompidas, mapeamentos mal formados ou outras coisas desagrad\u00e1veis que assombram pesadelos. A melhor abordagem \u00e9 deter esses inimigos na porta \u2014 atrav\u00e9s da aplica\u00e7\u00e3o for\u00e7ada de esquemas \u2014 e lidar com eles \u00e0 luz do dia, em vez de mais tarde, quando come\u00e7arem a vaguear nas profundezas sombrias do seu c\u00f3digo de trabalho.<\/p>\n<p>A aplica\u00e7\u00e3o for\u00e7ada do esquema garante que a estrutura da sua tabela n\u00e3o mudar\u00e1, a menos que voc\u00ea mesmo confirme uma altera\u00e7\u00e3o. Isso evita a \"dilui\u00e7\u00e3o\" dos dados, que pode ocorrer quando novas colunas s\u00e3o adicionadas com tanta frequ\u00eancia que tabelas antes valiosas e compactadas perdem seu significado e utilidade devido a um excesso de dados. Incentivando voc\u00ea a ser intencional, estabelecer altos padr\u00f5es e esperar alta qualidade, a aplica\u00e7\u00e3o for\u00e7ada do esquema faz exatamente o que foi projetado \u2014 ajuda voc\u00ea a permanecer diligente e suas tabelas a ficarem limpas.<\/p>\n<p>Se, ao considerar mais a fundo, voc\u00ea decidir que deve realmente <i>\u00e9 necess\u00e1rio<\/i> adicionar uma nova coluna \u2014 sem problemas, aqui est\u00e1 uma corre\u00e7\u00e3o em uma linha. A solu\u00e7\u00e3o \u00e9 a evolu\u00e7\u00e3o do esquema!<\/p>\n<h2>O que \u00e9 a evolu\u00e7\u00e3o do esquema?<\/h2>\n<p>\nA evolu\u00e7\u00e3o do esquema \u00e9 uma funcionalidade que permite aos usu\u00e1rios facilmente modificar o esquema atual da tabela de acordo com dados que mudam ao longo do tempo. \u00c9 mais comumente utilizada ao executar uma opera\u00e7\u00e3o de adi\u00e7\u00e3o ou reescrita, para adaptar automaticamente o esquema para incluir uma ou mais novas colunas.<\/p>\n<h2>Como funciona a evolu\u00e7\u00e3o do esquema?<\/h2>\n<p>\nSeguindo o exemplo da se\u00e7\u00e3o anterior, os desenvolvedores podem facilmente usar a evolu\u00e7\u00e3o do esquema para adicionar novas colunas que anteriormente foram rejeitadas devido a incompatibilidade com o esquema. A evolu\u00e7\u00e3o do esquema \u00e9 ativada adicionando <code>.option('mergeSchema', 'true')<\/code> ao seu comando Spark <code>.write ou .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>\nPara visualizar o gr\u00e1fico, execute a seguinte consulta 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=\"Imers\u00e3o no Delta Lake: aplica\u00e7\u00e3o obrigat\u00f3ria e evolu\u00e7\u00e3o do esquema\" src=\"\/wp-content\/uploads\/2020\/05\/873ce67da00f69696d5b9328bd90793a.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nComo alternativa, voc\u00ea pode definir esta op\u00e7\u00e3o para toda a sess\u00e3o Spark, adicionando <code>spark.databricks.delta.schema.autoMerge = True<\/code> na configura\u00e7\u00e3o do Spark. Mas use isso com cuidado, pois a aplica\u00e7\u00e3o for\u00e7ada do esquema n\u00e3o ir\u00e1 mais alert\u00e1-lo sobre incompatibilidades inesperadas.<\/p>\n<p>Incorporando ao seu pedido o par\u00e2metro <code>mergeSchema<\/code>, todas as colunas que estiverem presentes no DataFrame, mas ausentes na tabela de destino, ser\u00e3o automaticamente adicionadas ao final do esquema durante a transa\u00e7\u00e3o de grava\u00e7\u00e3o. Campos aninhados tamb\u00e9m podem ser adicionados e ser\u00e3o inclu\u00eddos no final das colunas correspondentes da estrutura.<\/p>\n<p>Engenheiros e cientistas podem usar esta op\u00e7\u00e3o para adicionar novas colunas (como uma m\u00e9trica monitorada recentemente ou uma coluna de vendas deste m\u00eas) \u00e0s suas tabelas de produ\u00e7\u00e3o de aprendizado de m\u00e1quina existentes, sem quebrar os modelos existentes baseados em colunas antigas. <\/p>\n<p>Os seguintes tipos de altera\u00e7\u00f5es de esquema s\u00e3o permitidas no contexto da evolu\u00e7\u00e3o do esquema ao adicionar ou reescrever uma tabela:<\/p>\n<ul>\n<li>Adi\u00e7\u00e3o de novas colunas (este \u00e9 o cen\u00e1rio mais comum)<\/li>\n<li>Altera\u00e7\u00e3o de tipos de dados de NullType -&gt; qualquer outro tipo ou eleva\u00e7\u00e3o de ByteType -&gt; ShortType -&gt; IntegerType<\/li>\n<\/ul>\n<p>\nOutras altera\u00e7\u00f5es, n\u00e3o permitidas no contexto da evolu\u00e7\u00e3o do esquema, exigem que o esquema e os dados sejam reescritos atrav\u00e9s da adi\u00e7\u00e3o <code>.option(&quot;overwriteSchema&quot;, &quot;true&quot;)<\/code>. Por exemplo, se a coluna \"Foo\" era originalmente do tipo inteiro e o novo esquema fosse do tipo string, ent\u00e3o todos os arquivos Parquet (dados) precisariam ser reescritos. Altera\u00e7\u00f5es como estas incluem:<\/p>\n<ul>\n<li>remo\u00e7\u00e3o da coluna<\/li>\n<li>altera\u00e7\u00e3o do tipo de dados de uma coluna existente (in-place)<\/li>\n<li>renomea\u00e7\u00e3o de colunas que diferem apenas por mai\u00fasculas e min\u00fasculas (por exemplo, \"Foo\" e \"foo\")<\/li>\n<\/ul>\n<p>\nFinalmente, com o pr\u00f3ximo lan\u00e7amento do Spark 3.0, o DDL expl\u00edcito ser\u00e1 totalmente suportado (usando ALTER TABLE), permitindo que os usu\u00e1rios realizem as seguintes opera\u00e7\u00f5es em esquemas de tabelas:<\/p>\n<ul>\n<li>adi\u00e7\u00e3o de colunas<\/li>\n<li>altera\u00e7\u00e3o de coment\u00e1rios de colunas<\/li>\n<li>configura\u00e7\u00e3o de propriedades da tabela que definem o comportamento da tabela, como a defini\u00e7\u00e3o da dura\u00e7\u00e3o de reten\u00e7\u00e3o do log de transa\u00e7\u00f5es.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Qual \u00e9 a vantagem da evolu\u00e7\u00e3o do esquema?<\/h2>\n<p>\nA evolu\u00e7\u00e3o do esquema pode ser usada sempre que voc\u00ea <i>pretende<\/i> modificar o esquema de sua tabela (em contraste com situa\u00e7\u00f5es em que voc\u00ea acidentalmente adicionou colunas ao seu DataFrame que n\u00e3o deveriam estar l\u00e1). Esta \u00e9 a maneira mais simples de migrar seu esquema, pois adiciona automaticamente os nomes de coluna e tipos de dados corretos sem a necessidade de declar\u00e1-los explicitamente.<\/p>\n<h2>Conclus\u00e3o<\/h2>\n<p>\nA aplica\u00e7\u00e3o for\u00e7ada do esquema reverte quaisquer novas colunas ou outras altera\u00e7\u00f5es no esquema que n\u00e3o sejam compat\u00edveis com sua tabela. Ao estabelecer e manter esses altos padr\u00f5es, analistas e engenheiros podem confiar que seus dados t\u00eam o mais alto n\u00edvel de integridade, pensando sobre isso de forma clara e precisa, o que lhes permite tomar decis\u00f5es empresariais mais eficazes.<\/p>\n<p>Por outro lado, a evolu\u00e7\u00e3o do esquema complementa a aplica\u00e7\u00e3o for\u00e7ada, simplificando <i>as altera\u00e7\u00f5es<\/i> autom\u00e1ticas do esquema. No final das contas, isso n\u00e3o deveria ser complicado \u2014 adicionar uma coluna.<\/p>\n<p>A aplica\u00e7\u00e3o for\u00e7ada do esquema \u00e9 o yang, enquanto a evolu\u00e7\u00e3o do esquema \u00e9 o yin. Quando usadas em conjunto, essas funcionalidades tornam mais f\u00e1cil do que nunca filtrar o ru\u00eddo e ajustar o sinal.<\/p>\n<p><i>Gostar\u00edamos tamb\u00e9m de agradecer a Mukul Murti e Pranav Anand por suas contribui\u00e7\u00f5es a este artigo.<\/i><\/p>\n<p>Outros artigos desta s\u00e9rie:<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/08\/21\/diving-into-delta-lake-unpacking-the-transaction-log.html\">Mergulhando no Delta Lake: desvendando o log de transa\u00e7\u00f5es<\/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=\"Por que no hosting comum a administra\u00e7\u00e3o do PrestaShop \u00e9 lenta, e no seu n\u00e3o \u00e9?\" 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>Artigos relacionados<\/h2>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/blog\/2019\/08\/14\/productionizing-machine-learning-with-delta-lake.html\">Aprendizado de m\u00e1quina de n\u00edvel empresarial com Delta Lake<\/a><\/noindex><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/databricks.com\/discover\/data-lakes\/introduction\">O que \u00e9 um lago de dados?<\/a><\/noindex><\/p>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/otus.pw\/J1P5\/\">Saiba mais sobre o curso<\/a><\/noindex><\/p>\n<p>Fonte: <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.3 - 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\/pt\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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\udd47 Mergulhando no Delta Lake: aplica\u00e7\u00e3o for\u00e7ada e evolu\u00e7\u00e3o do esquema | ProHoster","description":"Ol\u00e1, Habr!","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/pogruzhenie-v-delta-lake-prinuditelnoe-primenenie-i-evolyucziya-shemy","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/82038","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=82038"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/82038\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/82039"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=82038"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=82038"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=82038"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}