将Parse文件从Gridstore迁移到S3

时间:2017-01-19 08:33:03

标签: parse-platform

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

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

现在我使用sashido

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

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

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

1 个答案:

答案 0 :(得分:1)

也许您对我尝试的解决方案感兴趣。这不是一个简单的操作,但我使用我的解析服务器配置成功迁移了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!";

?>

正确设置您的解析网址。

想象一下,您想要使用字段_User从类imageProfile迁移文件,因此请务必通过$fileField = "imageProfile"; $class = "_User"

为每个类的任何字段运行该代码。

我做了一个愚蠢的解决方案,并行工作,这将跳过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"

所以你会像以下一样运行循环:

对象0,3,6

对象1,4,7

对象2,5,8

祝你好运,快点!它会在几天后关闭。