Página 1 de 1

Problemas com restauração de backup

Enviado: 21 Jan 2013, 16:10
por denisbr
Boa tarde a todos, tenho um cliente que possui uma loja virtual de vendas de CDs feita com Opencart e como preciso fazer alguns ajustes, fiz uma cópia dos arquivos para o meu ambiente de desenvolvimento, bem como um backup do banco de dados (utilizando o mysqldump).

Quando faço a importação do backup para o meu ambiente de desenvolvimento, as palavras com acentuação estão vindo "cortadas" , por exemplo a palavra "Grandes Sucessos - Sábado" vem somente "Grandes Sucessos - S" o conteúdo após o acento não retorna nada.

O que verifiquei é que no arquivo .sql (gerado no backup) tem tem comandos como:
Código: Selecionar todos
INSERT INTO `product_description` VALUES (4858, 2, 0x4772616e646573205375636573736f73202d2053e16261646f, 0x3c703e3031202d2053266161637574653b6261646f3c6272202f3e3032202d204465205175652056616c6520546572205475646f204e6120566964613c6272202f3e3033202d20486579213c6272202f3e3034202d204e696e6775266561637574653b6d2056616920546520416d617220436f6d6f20457520546520416d65693c6272202f3e3035202d204d6520457371756563692064652056697665723c6272202f3e3036202d2045737175652663636564696c3b613c6272202f3e3037202d204e266174696c64653b6f2054656d2050726f626c656d613c6272202f3e3038202d20566f632665636972633b204e266174696c64653b6f2053616265206f2051756520266561637574653b20416d61723c6272202f3e3039202d20457520517565726f204170656e617320436172696e686f3c6272202f3e3130202d2050616c61767261732c2050616c61767261732e2e2e3c6272202f3e3131202d205175656d204e6567612061204c757a2c204e6120536f6d62726120566169204d6f727265723c6272202f3e3132202d20446f636520456e67616e6f3c6272202f3e3133202d20446575732c204d657520446575732c204d657520446575733c6272202f3e3134202d204c757a657320646120526962616c74613c2f703e, '', '');
Ao invés de:
Código: Selecionar todos
insert  into `product_description`(`product_id`,`language_id`,`name`,`description`,`meta_description`,`meta_keyword`) values ('4858','2','Grandes Sucessos - Sábado','<p>01 - S&aacute;bado<br />02 - De Que Vale Ter Tudo Na Vida<br />03 - Hey!<br />04 - Ningu&eacute;m Vai Te Amar Como Eu Te Amei<br />05 - Me Esqueci de Viver<br />06 - Esque&ccedil;a<br />07 - N&atilde;o Tem Problema<br />08 - Voc&ecirc; N&atilde;o Sabe o Que &eacute; Amar<br />09 - Eu Quero Apenas Carinho<br />10 - Palavras, Palavras...<br />11 - Quem Nega a Luz, Na Sombra Vai Morrer<br />12 - Doce Engano<br />13 - Deus, Meu Deus, Meu Deus<br />14 - Luzes da Ribalta</p>','','');
A codificação das duas bases de dados estão iguais.

Não estou utilizando a ferramenta de backup/restaurar do Opencart porque quando mando salvar o backup está dando um erro de limite de memória do PHP e estou aguardando o provedor aumentar o limite.
Código: Selecionar todos
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 80 bytes) in /home/sites/centersom.com.br/web/loja/system/database/mysql.php on line 29 
Alguém consegue me dar uma sugestão?

Re: Problemas com importação

Enviado: 23 Jan 2013, 13:52
por denisbr
Boa tarde, então o problema do backup e restauração eu resolvi fazendo o backup usando a ferramenta SqlYOG para Windows que fez o backup com as informações corretas. Depois descobri que as informações estavam vindo com o formato
Código: Selecionar todos
INSERT INTO `product_description` VALUES (4858, 2, 0x4772616e646573205375636573736f73202d2053e16261646f, 0x3c703e3031202d2053266161637574653b6261646f3c6272202f3e3032202d204465205175652056616c6520546572205475646f204e6120566964613c6272202f3e3033202d20486579213c6272202f3e3034202d204e696e6775266561637574653b6d2056616920546520416d617220436f6d6f20457520546520416d65693c6272202f3e3035202d204d6520457371756563692064652056697665723c6272202f3e3036202d2045737175652663636564696c3b613c6272202f3e3037202d204e266174696c64653b6f2054656d2050726f626c656d613c6272202f3e3038202d20566f632665636972633b204e266174696c64653b6f2053616265206f2051756520266561637574653b20416d61723c6272202f3e3039202d20457520517565726f204170656e617320436172696e686f3c6272202f3e3130202d2050616c61767261732c2050616c61767261732e2e2e3c6272202f3e3131202d205175656d204e6567612061204c757a2c204e6120536f6d62726120566169204d6f727265723c6272202f3e3132202d20446f636520456e67616e6f3c6272202f3e3133202d20446575732c204d657520446575732c204d657520446575733c6272202f3e3134202d204c757a657320646120526962616c74613c2f703e, '', '');
por causa dos campos do tipo BLOB que para serem exibidos corretamente deveriam ser convertidos.

Agora estou com outro problema:
Estou fazendo uma rotina de importação de produtos para o Opencart a partir de um arquivo CSV.
O arquivo fornecido pelo cliente possui tamanho aproximado de 14MB e conta com cerca de 60000 linhas de produtos, e quando inicio a importação, ela leva cerca de 20 minutos (as vezes mais). Acho exagerado o tempo, visto que no site original (não em wordpress) o processo é super rápido, e também, quando faço a leitura do arquivo e mando somente gravar os produtos em uma tabela que não faz parte da estrutura do Opencart o processo é rápido. Imagino que o problema possa estar na estrutura de tabelas do opencart.

Os procedimentos que estou adotando são:
1. Upload do arquivo CSV
2. Cópia do arquivo do diretório temporário para um diretório fixo onde o Opencart está instalado
3. Inicio a leitura de cada linha usando um for
4. A cada linha, os campos são separados por ";", então faço um explode da linha, armazenando cada campo em um array
5. Pesquiso no banco de dados se um determinado produto está cadastrado usando o código de barras como campo para verificação
5.1 Se o produto estiver cadastrado, atualizo as informações nas tabelas: product, product_description e product_attribute
5.2 Se o produto não estiver cadastrado, faço um novo cadastro, inserindo as informações também nas tabelas product, product_description e product_attribute

Este processo está bastante lento.

Como já informado, tentei somente:
1. Upload do arquivo CSV
2. Cópia do arquivo do diretório temporário para um diretório fixo onde o Opencart está instalado
3. Inicio a leitura de cada linha usando um for
4. A cada linha, os campos são separados por ";", então faço um explode da linha, armazenando cada campo em um array
5. Inserir os produtos numa tabela não relacionada com o opencart, usando o comando:
Código: Selecionar todos
"INSERT INTO produtos_importados VALUES('', '" . trim($array[0]) . "', '" . $array[1] . "', '" . $array[2] . "', '" . $array[3] . "', '" . $array[4] . "', '" . $array[5] . "', '" . $array[6] . "', '" . $array[9] . "', '" . $array[10] . "', '" . $array[11] . "', '" . $array[13] . "', '" . $array[14] . "', '" .  $array[23] . "', '" . $date . "')"
E este processo é super rápido.

Segue o código que estou usando para a importação:
Código: Selecionar todos
function upload( $filename ) {
		global $config;
		global $log;
		$config = $this->config;
		$log = $this->log;
		set_error_handler('error_handler_for_export',E_ALL);
		register_shutdown_function('fatal_error_shutdown_handler_for_export');
		$database =& $this->db;
		set_time_limit(0);
		
		$arrayCadastrados = array();
		$arrayNovos = array();
		$handle = file($filename);
		// Busca a quantidade de registros
		$count = count($handle);
		$data = array();
				
		for($for=0; $for<=$count; $for++) {
			$linha = explode(';', $handle[$for]);
			// Armazena num array somente as 25 primeiras colunas (somente estas interessam para a importação)
			for ($i = 0; $i < 25; $i++) {
				$data[$i] = $linha[$i];
			}
						
			if ($data[9] == 1) {
				$ind_estoque = 7;
			} else {
				$ind_estoque = 5;
			}
					
			// Formatando os valores das colunas
			$i = 0;
			$descricao = "";                    
			$codigo_produto = "";
			$codigo_barras = $data[0];
			$descricao_produto = str_replace("\"","\\\"",$data[1]);
			$descricao_produto = ucwords(strtolower($descricao_produto));
			$autor = str_replace("\"","\\\"",$data[2]);
			$autor = ucwords(strtolower($autor));
			if (!empty($data[4]))
				$peso = str_replace(",",".",$data[4]);
			else
				$peso = 0;
			
			if (!empty($data[10]))
				$quantidade = $data[10];
			else
				$quantidade = 0;
			
			$preco = str_replace(".","",$data[5]);
			$preco = str_replace(",",".",$preco);

			// Buscando a categoria do produto
			switch($data[3]) {
				case 'CN':
				case 'CI':
					$array[3] = 1;
					break;
				case 'DN':
				case 'DI':
				case 'MK':
				case 'V':
				case 'VI':
					$array[3] = 2;
					break;
				case 'AI':
				case 'IM':
					$array[3] = 3;
					break;
				default:
					$array[3] = 4;
					break;
			} 
		
			// Buscando no banco de dados se o produto está cadastrado
			$sql = "select pd.product_id from product_description pd LEFT JOIN product_attribute pa ON (pd.product_id = pa.product_id) where upper(CONVERT (pd.name using utf8)) = '".strtoupper($descricao_produto)."' and pa.text = '".$codigo_barras."'";                                                
			$result = $database->query( $sql );                    

			// Se retornar algum valor é porque o produto está cadastrado, então atualizar as informações
			if ($result->num_rows > 0) {
				$codigo_produto = $result->row['product_id'];
				$sql = sprintf("UPDATE product SET status = 1, model='%s', price = %s, quantity = %s, stock_status_id = %s WHERE product_id = %s",$descricao_produto,$preco,$quantidade,$ind_estoque,$codigo_produto);
				$this->db->query($sql);
				$sql2 = sprintf("UPDATE product_description SET name = '%s', description='%s' WHERE product_id = %s",$descricao_produto,$descricao,$codigo_produto);
				$this->db->query($sql2);
				$sql6 = sprintf("DELETE FROM product_to_category WHERE product_id = %s",$codigo_produto);
				$this->db->query($sql6);                                                        
				$sql3 = sprintf("UPDATE product_to_category SET category_id = %s WHERE product_id = %s",$array[3],$codigo_produto);
				$this->db->query($sql3);
				$sql4 = sprintf("DELETE FROM product_attribute WHERE product_id = %s AND attribute_id = 12",$codigo_produto);
				$this->db->query($sql4);
				$sql5 = sprintf("INSERT INTO product_attribute (product_id,attribute_id,language_id,text) VALUES (%s,%s,%s,\"%s\")",$codigo_produto,12,2,$autor);
				$this->db->query($sql5);                                                        
				$sql6 = sprintf("DELETE FROM product_attribute WHERE product_id = %s AND attribute_id = 13",$codigo_produto);
				$this->db->query($sql6);
				$sql7 = sprintf("INSERT INTO product_attribute (product_id,attribute_id,language_id,text) VALUES (%s,%s,%s,\"%s\")",$codigo_produto,13,2,$codigo_barras);                        
				$this->db->query($sql7);
				$arrayCadastrados[] = $codigo_barras;
			} else {
				// Senão retornar valor, cadastra o produto
				$sql = sprintf("INSERT INTO product (model, price, weight,quantity, stock_status_id,location, status) VALUES ('%s',%s,%s,%s,%s,2,1)",$descricao_produto,$preco,$peso,$quantidade,$ind_estoque);
				$this->db->query($sql);                  
				$codigo_produto = $this->db->getLastId();
				$sql2 = sprintf("INSERT INTO product_description (product_id, language_id,name,description,meta_description,meta_keyword) VALUES (%s,2,\"%s\",\"%s\",\"\",\"\")",$codigo_produto,$descricao_produto,$descricao);
				$this->db->query($sql2);
				$sql3 = sprintf("INSERT INTO product_to_category (product_id,category_id) VALUES (%s,%s)",$codigo_produto,$array[3]);
				$this->db->query($sql3);
				$sql4 = sprintf("INSERT INTO product_to_store (product_id,store_id) VALUES (%s,0)",$codigo_produto);                        
				$this->db->query($sql4);
				$sql5 = sprintf("INSERT INTO product_attribute (product_id,attribute_id,language_id,text) VALUES (%s,%s,%s,\"%s\")",$codigo_produto,12,2,$autor);
				$this->db->query($sql5);
				$sql6 = sprintf("INSERT INTO product_attribute (product_id,attribute_id,language_id,text) VALUES (%s,%s,%s,\"%s\")",$codigo_produto,13,2,$codigo_barras);                        
				$this->db->query($sql6);
				$arrayNovos[] = $codigo_barras;
			}
            $data = array();
        }
		return TRUE;
}
Alguém consegue me dar alguma orientação?