将 Parse 文件从 Gridstore 迁移到 S3

Migrating Parse files from Gridstore to S3

我们将数据(没有文件)迁移到 mLabHeroku。所以旧文件仍在 Parse.

从那时起,添加的任何新文件都会进入 Gridstore,这是 mLab 的默认文件存储。

现在我使用 sashido

将旧的解析文件从 Parse 迁移到 S3 Bucket

文件已迁移,可以使用 Heroku 中的 S3Adapter 访问。

但是 Gridstore 上的文件现在无法访问。如何将它们迁移到同一个 S3 存储桶 并更改 mLab 中的引用?

也许您对我试过的解决方案感兴趣。这不是一个简单的操作,但我使用我的解析服务器配置成功迁移了 3 个数据库。

它基于 PHP 脚本(使用 Parse PHP SDK)运行 遍历每个对象,它从 Parse.com 获取文件并设置它(使用任何适配器配置)在您自己的服务器中。

脚本如下所示:

<?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    date_default_timezone_set('America/New_York');
    
    $fileField = $argv[1];
    $class     = $argv[2];
    
    require_once 'vendor/autoload.php';
    use Parse\ParseObject;
    use Parse\ParseQuery;
    use Parse\ParseACL;
    use Parse\ParsePush;
    use Parse\ParseUser;
    use Parse\ParseInstallation;
    use Parse\ParseException;
    use Parse\ParseAnalytics;
    use Parse\ParseFile;
    use Parse\ParseCloud;
    use Parse\ParseClient;
    
    $app_id     = "******";
    $rest_key   = "******";
    $master_key = "******";
    
    ParseClient::initialize($app_id, $rest_key, $master_key);
    ParseClient::setServerURL('http://localhost:1338/', 'parse');
    
    $query = new ParseQuery($class);
    $query->ascending("createdAt"); // it's just my preference
    $query->exists($fileField);
    $query->limit(1);
    
    $count = $query->count();
    for ($i = 0; $i < $count; $i = $i + 1) {
        try {
            $query->skip($i);
            // get Entry
            $entryWithFile = $query->first();
            
            // get file
            $parseFile = $entryWithFile->get($fileField);
            // filename
            $fileName  = $parseFile->getName();

            // if the file is hosted in Parse, do the job, otherwise continue with the next one
            if (strpos($fileName, "tfss-") === false) {
                echo "\nThis is already an internal file, skipping...";
                continue;
            }
            
            $newFileName = str_replace("tfss-", "", $fileName);
            $binaryFile  = file_get_contents($parseFile->getURL());
            
            $newFile = ParseFile::createFromData($binaryFile, $newFileName);
            
            $entryWithFile->set($fileField, $newFile);
            $entryWithFile->save(true);
            
            echo "\nFile saved\n";
        }
        catch (Exception $e) {
            // The conection with mongo or the server could be off for some second, let's retry it ;)
            sleep(10);
            continue;
        }
    }
    
    echo "\n";
    echo "END!";
    
?>

正确设置您的解析 url。

假设您要从 class _User 迁移字段为 imageProfile 的文件,因此请务必传递 $fileField = "imageProfile"; $class = "_User".

运行 每个字段的代码 class.

我做了一个并行工作的愚蠢解决方案,它会跳过 for 循环中的步骤,例如:

<?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    date_default_timezone_set('America/New_York');
    
    $index     = $argv[1];
    $of        = $argv[2];
    $fileField = $argv[3];
    $class     = $argv[4];
    
    require_once 'vendor/autoload.php';
    use Parse\ParseObject;
    use Parse\ParseQuery;
    use Parse\ParseACL;
    use Parse\ParsePush;
    use Parse\ParseUser;
    use Parse\ParseInstallation;
    use Parse\ParseException;
    use Parse\ParseAnalytics;
    use Parse\ParseFile;
    use Parse\ParseCloud;
    use Parse\ParseClient;
    
    $app_id     = "********";
    $rest_key   = "********";
    $master_key = "********";
    
    ParseClient::initialize($app_id, $rest_key, $master_key);
    ParseClient::setServerURL('http://localhost:1338/', 'parse');
    
    $query = new ParseQuery($class);
    $query->ascending("createdAt");
    $query->exists($fileField);
    $query->limit(1);
    
    $count = $query->count();
    for ($i = $index; $i < $count; $i = $i + $of) {
        try {
            $query->skip($i);
            // get Entry
            $entryWithFile = $query->first();
            
            // get file
            $parseFile = $entryWithFile->get($fileField);
            // filename
            $fileName  = $parseFile->getName();

            // if the file is hosted in Parse, do the job, otherwise continue with the next one
            if (strpos($fileName, "tfss-") === false) {
                echo "\nThis is already an internal file, skipping...";
                continue;
            }
            
            $newFileName = str_replace("tfss-", "", $fileName);
            $binaryFile  = file_get_contents($parseFile->getURL());
            
            $newFile = ParseFile::createFromData($binaryFile, $newFileName);
            
            $entryWithFile->set($fileField, $newFile);
            $entryWithFile->save(true);
            
            echo "\nFile saved\n";
        }
        catch (Exception $e) {
            // The conection with mongo or the server could be off for some second, let's retry it ;)
            sleep(10);
            continue;
        }
    }
    
    echo "\n";
    echo "END!";
    
?>

所以如果你像以前一样配置$fileField$class,你可以打开3个线程和运行:

php migrator.php 0 3 "imageProfile" "_User"

php migrator.php 1 3 "imageProfile" "_User"

php migrator.php 2 3 "imageProfile" "_User"

所以你会有循环 运行ning 像:

对象 0、3、6

对象 1、4、7

对象 2、5、8

祝你好运,快点!过几天就要关了。