protected function writeTable(CsvFile $csv, $outputTable, $incremental, $primaryKey) { try { $tableNameArr = explode('.', $outputTable); $bucketId = $tableNameArr[0] . "." . $tableNameArr[1]; $tableName = $tableNameArr[2]; } catch (ContextErrorException $e) { throw new UserException("Wrong output table name.", $e); } if (!count($csv->getHeader())) { throw new ApplicationException("Trying to upload an empty file"); } try { if (!$this->storageApi->bucketExists($bucketId)) { $bucketArr = explode('.', $bucketId); $this->storageApi->createBucket(str_replace('c-', '', $bucketArr[1]), SapiClient::STAGE_IN, 'DB Extractor data bucket'); } if (!$this->storageApi->tableExists($outputTable)) { $this->storageApi->createTableAsync($bucketId, $tableName, $csv, array('primaryKey' => $primaryKey)); } else { // handle unexpected temporary errors like "unable to fork()" $success = false; $exception = null; for ($i = 0; $i < 2 && !$success; $i++) { try { $this->storageApi->writeTableAsync($outputTable, $csv, array('incremental' => $incremental)); $success = true; } catch (\Exception $e) { $exception = $e; $this->logger->warning("Error writing to SAPI", ['exception' => $exception]); } sleep(1); } if (!$success) { throw $exception; } } } catch (ClientException $e) { if ($e->getCode() < 500) { throw new UserException($e->getMessage(), $e); } else { throw new ApplicationException($e->getMessage(), $e); } } $this->logger->info("Table " . $tableName . " imported to Storage API"); }
/** * * Upload CSV file to storage API * * @param $queryNumber * @param $table * @return bool * @throws \Exception * @throws \Keboola\StorageApi\ClientException */ private function _uploadCsvFile($queryNumber, $table) { if (!isset($this->_csvFiles[$queryNumber])) { return false; } $csvHandle = $this->_csvFiles[$queryNumber]["handle"]; $tableId = $this->storageApiBucket . '.' . $table; if (!isset($this->_sapiTableCache[$tableId]) && $this->storageApi->tableExists($tableId)) { $this->_sapiTableCache[$tableId] = $this->storageApi->getTable($tableId); } try { if (isset($this->_sapiTableCache[$tableId])) { $this->storageApi->writeTableAsync($tableId, $csvHandle, array("incremental" => true)); } else { $this->storageApi->createTableAsync($this->storageApiBucket, $table, $csvHandle, array("primaryKey" => "ex__primary")); $this->_sapiTableCache[$tableId] = $this->storageApi->getTable($tableId); } } catch (Exception $e) { throw new UserException($e->getMessage(), $e); } return true; }
public function testReadTablesS3Redshift() { // Create bucket if (!$this->client->bucketExists("in.c-docker-test-redshift")) { $this->client->createBucket("docker-test-redshift", Client::STAGE_IN, "Docker Testsuite", "redshift"); } // Create table if (!$this->client->tableExists("in.c-docker-test-redshift.test")) { $csv = new CsvFile($this->tmpDir . "/upload.csv"); $csv->writeRow(["Id", "Name"]); $csv->writeRow(["test", "test"]); $this->client->createTableAsync("in.c-docker-test-redshift", "test", $csv); $this->client->setTableAttribute("in.c-docker-test-redshift.test", "attr1", "val2"); } $root = $this->tmpDir; $reader = new Reader($this->client); $configuration = [["source" => "in.c-docker-test-redshift.test", "destination" => "test-redshift.csv"]]; $reader->downloadTables($configuration, $root . "/download", "s3"); $adapter = new TableManifestAdapter(); $manifest = $adapter->readFromFile($root . "/download/test-redshift.csv.manifest"); $this->assertEquals("in.c-docker-test-redshift.test", $manifest["id"]); $this->assertEquals("val2", $manifest["attributes"][0]["value"]); $this->assertS3info($manifest); }