{"id":4459,"date":"2018-06-19T14:13:45","date_gmt":"2018-06-19T17:13:45","guid":{"rendered":"https:\/\/blog.clusterweb.com.br\/?p=4459"},"modified":"2018-06-19T14:13:45","modified_gmt":"2018-06-19T17:13:45","slug":"migracao-de-arquivos-do-tipo-blob-para-sistema-de-arquivos","status":"publish","type":"post","link":"https:\/\/blog.clusterweb.com.br\/?p=4459","title":{"rendered":"MIGRA\u00c7\u00c3O DE ARQUIVOS DO TIPO BLOB PARA SISTEMA DE ARQUIVOS"},"content":{"rendered":"<div>\n<h1>ESTRUTURA DA TABELA E INSER\u00c7\u00c3O DE REGISTROS<\/h1>\n<\/div>\n<div>O intuito deste artigo \u00e9 compartilhar um pouco da minha experi\u00eancia com migra\u00e7\u00e3o de\u00a0<em>arquivos BLOB<\/em>\u00a0em um banco de dados\u00a0<em>Oracle<\/em>\u00a0para sistema de arquivos utilizando\u00a0<em>Python<\/em>.<\/p>\n<p>Antes de efetivamente partirmos para o c\u00f3digo de migra\u00e7\u00e3o, vamos ver os dados de acesso e como ser\u00e1 a estrutura da tabela.<\/p>\n<p>Utilizo os seguintes dados de acesso para o esquema no Oracle:<\/p>\n<ul>\n<li>user: desv<\/li>\n<li>pass: 123456<\/li>\n<li>service name: xe<\/li>\n<li>IP do host onde est\u00e1 o SGBD do Oracle: 192.168.1.131<\/li>\n<\/ul>\n<p>Vamos utilizar a estrutura da tabela a seguir:<\/p>\n<div class=\"codigo\">\n<pre>CREATE TABLE TB_ARQUIVO (\r\n\tCOD_ARQUIVO           NUMBER PRIMARY KEY,\r\n\tDTHINCLUSAO           DATE NOT NULL,\r\n\tARQUIVO               BLOB,\r\n\tDS_ARQUIVO            VARCHAR2(50 BYTE),\r\n\tDS_PATH_ARQUIVO       VARCHAR2(255 BYTE)\r\n);<\/pre>\n<\/div>\n<p><!--more--><br \/>\nA tabela TB_ARQUIVO cont\u00e9m as seguintes colunas:<\/p>\n<ul>\n<li>COD_ARQUIVO: coluna para identificar um registro como \u00fanico (chave prim\u00e1ria)<\/li>\n<li>DTHINCLUSAO: armazena a data de inclus\u00e3o do arquivo<\/li>\n<li>ARQUIVO: armazena um arquivo em formado PDF<\/li>\n<li>DS_ARQUIVO: define um nome para o arquivo<\/li>\n<li>DS_PATH_ARQUIVO: path, onde o arquivo ficar\u00e1 gravado em disco<\/li>\n<\/ul>\n<p>Vamos inserir alguns registros:<\/p>\n<div class=\"codigo\">INSERT INTO TB_ARQUIVO(COD_ARQUIVO,DS_ARQUIVO,DTHINCLUSAO) VALUES(1,&#8217;ORACLE&#8217;,&#8217;30\/05\/2016&#8242;);<br \/>\nINSERT INTO TB_ARQUIVO(COD_ARQUIVO,DS_ARQUIVO,DTHINCLUSAO) VALUES(2,&#8217;LINUX&#8217;,&#8217;31\/05\/2016&#8242;);<br \/>\nINSERT INTO TB_ARQUIVO(COD_ARQUIVO,DS_ARQUIVO,DTHINCLUSAO) VALUES(3,&#8217;BIGDATA&#8217;,&#8217;30\/05\/2017&#8242;);<br \/>\nINSERT INTO TB_ARQUIVO(COD_ARQUIVO,DS_ARQUIVO,DTHINCLUSAO) VALUES(4,&#8217;HADOOP&#8217;,&#8217;29\/05\/2017&#8242;);<br \/>\nINSERT INTO TB_ARQUIVO(COD_ARQUIVO,DS_ARQUIVO,DTHINCLUSAO) VALUES(5,&#8217;DATAMINING&#8217;,&#8217;01\/02\/2018&#8242;);<br \/>\nINSERT INTO TB_ARQUIVO(COD_ARQUIVO,DS_ARQUIVO,DTHINCLUSAO) VALUES(6,&#8217;PYTHON&#8217;,&#8217;01\/02\/2018&#8242;);<br \/>\nCOMMIT;<\/div>\n<p>O script SQL est\u00e1 dispon\u00edvel no seguinte link:\u00a0<a href=\"https:\/\/pastebin.com\/0FabU0qY\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/pastebin.com\/0FabU0qY<\/a><\/p>\n<p>Ap\u00f3s a inser\u00e7\u00e3o, precisamos adicionar os arquivos PDFs.<\/p>\n<p>Como s\u00e3o apenas seis registros, podemos adicionar os arquivos de forma r\u00e1pida pelo Oracle SQL Developer.<\/p>\n<p>No SQL Developer, ap\u00f3s a cria\u00e7\u00e3o da tabela e inser\u00e7\u00e3o dos registros, clique no nome da tabela &#8220;TB_ARQUIVO&#8221; e clique em &#8220;Dados&#8221;.<\/p>\n<p>Na ferramenta, dever\u00e1 ser exibido algo igual \u00e0 imagem a seguir:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem01_sqldev01.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem01_sqldev01.jpeg\" alt=\"\" width=\"500\" height=\"133\" border=\"0\" \/><\/a><\/div>\n<p>Agora, d\u00ea dois cliques abaixo da coluna ARQUIVO, onde aparece o nome &#8220;null&#8221;. Veja que aparece um \u00edcone com a imagem de um l\u00e1pis. Clique em cima do \u00edcone.<\/p>\n<p>Dever\u00e1 aparecer a janela da figura a seguir:<\/p>\n<div class=\"figura\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem02_sqldev02.jpeg\" alt=\"\" width=\"448\" height=\"416\" \/><\/div>\n<p>Clique na op\u00e7\u00e3o &#8220;Carregar&#8221; e selecione um arquivo PDF qualquer. Depois \u00e9 s\u00f3 repetir os passos anteriores para os demais registros. Observe a imagem a seguir:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem03_sqldev03.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem03_sqldev03.jpeg\" alt=\"\" width=\"500\" height=\"137\" border=\"0\" \/><\/a><\/div>\n<p>Veja que &#8220;null&#8221; foi substitu\u00eddo por &#8220;BLOB&#8221;, pois os arquivos PDF j\u00e1 foram inseridos na tabela, entretanto, falta efetivar a transa\u00e7\u00e3o. Basta clicar na op\u00e7\u00e3o onde o ponteiro do mouse est\u00e1 apontando, ou ent\u00e3o, teclar em F11.<\/p>\n<p>Ap\u00f3s as a\u00e7\u00f5es realizadas em banco, vamos partir para os requisitos para realizar a migra\u00e7\u00e3o.<\/p>\n<\/div>\n<h1>REQUISITOS DA MIGRA\u00c7\u00c3O<\/h1>\n<p>&nbsp;<\/p>\n<div>N\u00e3o basta simplesmente gravar todos os arquivos em disco de forma aleat\u00f3ria, para isso temos que seguir alguns requisitos.<\/p>\n<p>1\u00b0) Os arquivos dever\u00e3o ser gravados em disco, de acordo com o campo da data de inclus\u00e3o (DTHINCLUSAO), ou seja, dever\u00e1 ser criada uma hierarquia de diret\u00f3rios ano\/mes\/dia. Portanto, se um registro possui uma data 30\/05\/2016, o arquivo dever\u00e1 ser gravado em um diret\u00f3rio 2016\/05\/30.<\/p>\n<p>2\u00b0) Ao gravar em disco, duas colunas precisar\u00e3o ser atualizadas: DS_PATH_ARQUIVO com o path e DS_ARQUIVO com o nome do arquivo o qual foi gravado no sistema de arquivos.<\/p>\n<p>3\u00b0) Em rela\u00e7\u00e3o ao nome do arquivo, observe um cen\u00e1rio em que uma empresa possua centenas de milhares de arquivos em banco, devemos evitar a colis\u00e3o de nomes em disco, ent\u00e3o para contornar essa situa\u00e7\u00e3o, iremos utilizar o m\u00f3dulo uuid, identificador universalmente exclusivo, para gerar os nomes dos arquivos criando strings \u00fanicas que garantam unicidade.<\/p>\n<h1>C\u00d3DIGO DA MIGRA\u00c7\u00c3O<\/h1>\n<p>Para saber como configurar uma inst\u00e2ncia cliente do Oracle, e como configurar o Python para conectar ao banco de dados, h\u00e1 um artigo publicado anteriormente, explicando o passo a passo:\u00a0<a href=\"https:\/\/www.vivaolinux.com.br\/artigo\/Configurando-uma-instancia-do-Oracle-para-acesso-via-Python\/\">Configurando uma inst\u00e2ncia do Oracle para acesso via Python [Artigo]<\/a><\/p>\n<p>Vamos iniciar o c\u00f3digo realizando os imports dos m\u00f3dulos.<\/p>\n<div class=\"figura\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem04_imports.jpeg\" alt=\"\" width=\"236\" height=\"73\" \/><\/div>\n<p>O m\u00f3dulo &#8220;cx_Oracle&#8221; \u00e9 para conectar ao banco de dados, enquanto que o m\u00f3dulo &#8220;os&#8221; \u00e9 para manipula\u00e7\u00e3o de diret\u00f3rios, criando-os em disco. Por fim, o m\u00f3dulo &#8220;uuid&#8221;, para criar as strings que ser\u00e3o os nomes dos arquivos.<\/p>\n<p>Agora vamos criar tr\u00eas fun\u00e7\u00f5es: uma para conectar ao banco de dados, outra para escrever o arquivo em disco e a terceira fun\u00e7\u00e3o para criar o diret\u00f3rio.<\/p>\n<p>Fun\u00e7\u00e3o para conectar ao Oracle:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem05_funcao_oracle.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem05_funcao_oracle.jpeg\" alt=\"\" width=\"500\" height=\"72\" border=\"0\" \/><\/a><\/div>\n<p>Veja na imagem anterior que a fun\u00e7\u00e3o recebe quatro par\u00e2metros relacionados ao ambiente onde est\u00e1 executando o Oracle: schema, password, host e o service name. Na linha seis, eu concateno todas as informa\u00e7\u00f5es para formar a URL de conex\u00e3o e na linha sete, atrav\u00e9s da fun\u00e7\u00e3o &#8220;connect&#8221;, \u00e9 criada uma conex\u00e3o com o banco de dados.<\/p>\n<p>A nossa pr\u00f3xima fun\u00e7\u00e3o ser\u00e1 para gravar o arquivo &#8220;pdf&#8221; em disco:<\/p>\n<div class=\"figura\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem06_funcao_write_file.jpeg\" alt=\"\" width=\"482\" height=\"77\" \/><\/div>\n<p>Essa fun\u00e7\u00e3o recebe dois par\u00e2metros: data se refere ao conte\u00fado do arquivo &#8220;pdf&#8221; e filename ao nome do arquivo que ser\u00e1 gravado em disco.<\/p>\n<p>Na linha 12, veja que \u00e9 utilizado o modo &#8220;wb&#8221;, o qual significa escrita de bin\u00e1rios. Na linha 13, a fun\u00e7\u00e3o &#8220;write&#8221; \u00e9 a respons\u00e1vel por gravar o arquivo em disco.<\/p>\n<p>A fun\u00e7\u00e3o a seguir cria o diret\u00f3rio em disco:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem07_funcao_create_dir.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem07_funcao_create_dir.jpeg\" alt=\"\" width=\"500\" height=\"137\" border=\"0\" \/><\/a><\/div>\n<p>Relembrando, o 1\u00b0 requisito; O arquivo dever\u00e1 ser gravado em disco, em um diret\u00f3rio formado a partir da coluna &#8220;DTHINCLUSAO&#8221;.<\/p>\n<p>Veja que a fun\u00e7\u00e3o &#8220;criarDiretorioArquivo&#8221; recebe cinco par\u00e2metros: path (caminho do sistema de arquivos), ano, m\u00eas, dia e data (arquivo pdf).<\/p>\n<p>Observe as linhas 16 e 17, a vari\u00e1vel &#8220;caminho&#8221; realiza a concatena\u00e7\u00e3o de todo o path e a vari\u00e1vel &#8220;arquivo&#8221; concatena o path acrescido do nome do arquivo com a extens\u00e3o &#8220;.pdf&#8221;. Em um dos requisitos, foi mencionado que dever\u00edamos evitar a colis\u00e3o de nomes, ent\u00e3o para isso foi utilizado str(uuid.uuid1()). Est\u00e1 sendo criada uma cadeia de 32 d\u00edgitos hexadecimais e a fun\u00e7\u00e3o &#8220;str&#8221; faz a convers\u00e3o para string. Na linha 18 \u00e9 verificado se o diret\u00f3rio n\u00e3o existe, caso n\u00e3o exista ele ser\u00e1 criado, caso exista, o c\u00f3digo partir\u00e1 para a verifica\u00e7\u00e3o na linha 20, como o arquivo n\u00e3o existe ele ser\u00e1 criado com a chamada da fun\u00e7\u00e3o &#8220;write_data&#8221; na linha 21.<\/p>\n<p>Com a cria\u00e7\u00e3o dessas tr\u00eas fun\u00e7\u00f5es, nosso c\u00f3digo &#8220;main&#8221; ficar\u00e1 bem enxuto. Agora vamos para a fun\u00e7\u00e3o principal:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem08_main_01.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem08_main_01.jpeg\" alt=\"\" width=\"500\" height=\"127\" border=\"0\" \/><\/a><\/div>\n<p>Veja que eu poderia fornecer os dados de acesso de forma est\u00e1tica no c\u00f3digo, assim como o path, no entanto, considerando a possibilidade de executar o c\u00f3digo em v\u00e1rios ambientes (desenvolvimento, testes, homologa\u00e7\u00e3o&#8230;), prefiro fornecer esses dados em tempo de execu\u00e7\u00e3o.<\/p>\n<p>Vamos ao pr\u00f3ximo trecho do c\u00f3digo:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem09_main_02.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem09_main_02.jpeg\" alt=\"\" width=\"500\" height=\"91\" border=\"0\" \/><\/a><\/div>\n<p>Aqui eu fa\u00e7o a chamada \u00e0 primeira fun\u00e7\u00e3o criada: &#8220;conectarOracle&#8221;. Abro um cursor e executo uma consulta SQL na tabela &#8220;TB_ARQUIVO&#8221;, pois necessito de tr\u00eas informa\u00e7\u00f5es: o c\u00f3digo de cada registro, al\u00e9m da data de inclus\u00e3o e do arquivo em PDF, obtido do campo do tipo BLOB.<\/p>\n<p>Agora vamos para a \u00faltima parte do c\u00f3digo:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem10_main_03.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem10_main_03.jpeg\" alt=\"\" width=\"500\" height=\"185\" border=\"0\" \/><\/a><\/div>\n<p>Na linha 41, \u00e9 declarado um contador para cada migra\u00e7\u00e3o ser exibido o somat\u00f3rio parcial e no final da execu\u00e7\u00e3o ser exibida a quantidade de arquivos migrados. Depois \u00e9 necess\u00e1rio iterar no cursor para as vari\u00e1veis s_cod, s_dthinclusao e s_arquivo receberem os valores obtidos anteriormente pela consulta SQL. Para a estrutura de diret\u00f3rios ser gravada em disco, necessitamos acessar o valor da coluna &#8220;s_dthinclusao&#8221; e converter para string. Isso \u00e9 feito na linha 43, com o uso da fun\u00e7\u00e3o &#8220;strftime&#8221;.<\/p>\n<p>Na linha 45 chamamos a fun\u00e7\u00e3o &#8220;criarDiretorioArquivo&#8221;, que al\u00e9m de criar os diret\u00f3rios, tamb\u00e9m vai gravar o arquivo. No primeiro par\u00e2metro passamos o path do sistema de arquivos, nos segundo, terceiro e quarto par\u00e2metros, \u00e9 utilizado o operador de slice, para obter o ano, m\u00eas e dia, pois a data est\u00e1 sendo obtida assim: 2016\/05\/30. Portanto, o path \u00e9 concatenado com essa nova estrutura de diret\u00f3rios. E no \u00faltimo par\u00e2metro, &#8220;s_arquivo.read()&#8221; obtemos o arquivo BLOB para gravar em disco.<\/p>\n<p>Na linha 49 abrimos um novo cursor para executar a instru\u00e7\u00e3o SQL na linha seguinte, para atualizar as colunas ds_path_arquivo e ds_arquivo para cada registro.<\/p>\n<p>Agora, muita aten\u00e7\u00e3o quanto \u00e0 linha 51. O nome do arquivo gerado fica nesse formato b75b6632-33a5-11e8-8b38-847bebfeb61e concatenado com a extens\u00e3o do arquivo que \u00e9 &#8220;.pdf&#8221;, a string fica assim: b75b6632-33a5-11e8-8b38-847bebfeb61e.pdf. Essa string possui 40 caracteres, ent\u00e3o para obter todo o path para atualizar a coluna &#8220;ds_path_arquivo&#8221;, basta utilizar o slice file[:-41], assim vamos extrair tudo que estiver antes dos 40 caracteres do nome do arquivo. E para atualizar a coluna ds_arquivo com o nome do arquivo, extra\u00edmos os \u00faltimos 40 caracteres, utilizando file[-40:]. O terceiro par\u00e2metro &#8220;s_cod&#8221; \u00e9 para diferenciar cada registro que est\u00e1 sendo atualizado.<\/p>\n<p>Estou considerando o cen\u00e1rio do tudo ou nada, pois o commit s\u00f3 \u00e9 feito no final.<\/p>\n<p>No link a seguir \u00e9 poss\u00edvel baixar o c\u00f3digo de migra\u00e7\u00e3o:\u00a0<a href=\"https:\/\/pastebin.com\/UDQEjhuv\" target=\"_blank\" rel=\"nofollow noopener\">https:\/\/pastebin.com\/UDQEjhuv<\/a><\/p>\n<p>Por fim, basta executar pelo terminal, lembrando que \u00e9 necess\u00e1rio execut\u00e1-lo na m\u00e1quina do sistema de arquivos:<\/p>\n<p><strong><i class=\"fa fa-usd\"><\/i>\u00a0python MigracaoDados.py<\/strong><\/p>\n<p>Na imagem a seguir veja o resultado da execu\u00e7\u00e3o:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem11_execucao.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem11_execucao.jpeg\" alt=\"\" width=\"500\" height=\"400\" border=\"0\" \/><\/a><\/div>\n<p>Agora vamos ver como ficou a tabela no banco de dados:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem12_sqldeveloper.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem12_sqldeveloper.jpeg\" alt=\"\" width=\"500\" height=\"121\" border=\"0\" \/><\/a><\/div>\n<p>Apesar dos dados da coluna &#8220;ds_arquivo&#8221; parecerem todos iguais, h\u00e1 uma diferen\u00e7a de caracteres em todos os registros. Tamb\u00e9m veja que a coluna &#8220;ds_path_arquivo&#8221; tamb\u00e9m foi atualizada com o path onde o arquivo foi gravado.<\/p>\n<p>E na pr\u00f3xima imagem, os arquivos gravados em disco:<\/p>\n<div class=\"figura\"><a href=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/imagem13_files.jpeg\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/img.vivaolinux.com.br\/imagens\/artigos\/comunidade\/thumb_imagem13_files.jpeg\" alt=\"\" width=\"500\" height=\"306\" border=\"0\" \/><\/a><\/div>\n<p>Deve ter surgido alguma d\u00favida sobre o porqu\u00ea da n\u00e3o exclus\u00e3o da coluna &#8220;arquivo&#8221;, Pois n\u00e3o h\u00e1 sentido algum em manter esses dados duplicados (em banco e no sistema de arquivos). A exclus\u00e3o da coluna deve sim ser feita, por\u00e9m, depois de realizadas todas as valida\u00e7\u00f5es poss\u00edveis, como verifica\u00e7\u00e3o da integridade do arquivo, por exemplo, ver se um determinado arquivo que foi gravado em disco se corresponde efetivamente ao que est\u00e1 no banco.<\/p>\n<p>Caso v\u00e1 reutilizar esse c\u00f3digo de acordo com algum cen\u00e1rio da sua empresa, \u00e9 interessante renomear a coluna &#8220;arquivo&#8221; e verificar se a aplica\u00e7\u00e3o passar\u00e1 a enxergar esses arquivos em disco. Portanto, ap\u00f3s ter certeza de que a migra\u00e7\u00e3o foi realizada com sucesso e a aplica\u00e7\u00e3o n\u00e3o acessa mais a coluna com os arquivos bin\u00e1rios, a coluna poder\u00e1 ser exclu\u00edda da tabela.<\/p>\n<p>A crit\u00e9rio de informa\u00e7\u00e3o, esse c\u00f3digo foi utilizado em um cen\u00e1rio real na empresa a qual trabalho, onde tivemos que migrar pouco mais de 320 mil arquivos do banco para sistema de arquivos. O desempenho da migra\u00e7\u00e3o vai depender do poder de processamento da m\u00e1quina. Numa m\u00e1quina do ambiente de testes, com um hardware n\u00e3o t\u00e3o robusto, todos esses arquivos foram migrados em torno de 3h:30, enquanto que em outra m\u00e1quina com as configura\u00e7\u00f5es similares ao ambiente de produ\u00e7\u00e3o, todos os arquivos foram migrados em aproximadamente 2h.<\/p>\n<h1>CONCLUS\u00c3O<\/h1>\n<p>Espero que o artigo tenha sido relevante para o aprendizado e possa servir como base para atender alguma necessidade que a sua empresa tenha, basta realizar as devidas adapta\u00e7\u00f5es no c\u00f3digo, seguindo os requisitos de neg\u00f3cio estipulados.<\/p>\n<p>Qualquer sugest\u00e3o, cr\u00edtica ou d\u00favida, sinta-se a vontade e deixe nos coment\u00e1rios.<\/p>\n<p>At\u00e9 a pr\u00f3xima!<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>ESTRUTURA DA TABELA E INSER\u00c7\u00c3O DE REGISTROS O intuito deste artigo \u00e9 compartilhar um pouco da minha experi\u00eancia com migra\u00e7\u00e3o de\u00a0arquivos BLOB\u00a0em um banco de dados\u00a0Oracle\u00a0para sistema de arquivos utilizando\u00a0Python. Antes de efetivamente partirmos para o c\u00f3digo de migra\u00e7\u00e3o, vamos ver os dados de acesso e como ser\u00e1 a estrutura da tabela. Utilizo os seguintes [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[91,1082,1,730,830,42,51,495,514],"tags":[158,1176,353,366,173,355,509,1175],"class_list":["post-4459","post","type-post","status-publish","format-standard","hentry","category-banco-de-dados","category-centos-7-rhel-7","category-viazap","category-clusterweb","category-debian","category-leitura-recomendada","category-linux-linuxrs","category-profissional-de-ti","category-programacao","tag-arquivos","tag-blob","tag-de","tag-do","tag-migracao","tag-para","tag-sistema","tag-tipo"],"_links":{"self":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts\/4459","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4459"}],"version-history":[{"count":1,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts\/4459\/revisions"}],"predecessor-version":[{"id":4460,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=\/wp\/v2\/posts\/4459\/revisions\/4460"}],"wp:attachment":[{"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4459"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4459"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.clusterweb.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4459"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}