バージョン選択

フォーラム

メニュー

オンライン状況

34 人のユーザが現在オンラインです。 (22 人のユーザが フォーラム を参照しています。)
登録ユーザ: 2
ゲスト: 32
wagasasa nanasess もっと...

サイト内検索

プラグイン > 開発について > プラグインアップデートで既存データを移行したい

開発について

新規スレッドを追加する

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
h_tanaka
投稿日時: 2018/9/6 16:56
対応状況: −−−
仙人
登録日: 2016/7/22
居住地: 愛媛県
投稿: 566
プラグインアップデートで既存データを移行したい
既に公開済みの「特集ページ作成プラグイン」において、登録時にエラーになるというお問い合わせがありました。

実際にお客様の環境で試してみたところ、次のエラーが発生しました。
#1118 - Row size too large (> 1982). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In current row format, BLOB prefix of 768 bytes is stored inline.

このエラーメッセージを調べてみると次の情報がヒットしました。
https://github.com/EC-CUBE/ec-cube/issues/1804

このページの情報によると、エラーの原因はログ書き込み時のサイズ制限(約2KB)で、この問題を解決するには mySQL の設定を変更する必要があるとのことです。
ただ、共用サーバーではmySQLのバージョンを上げたり my.cnf を変更することができないため、プラグイン側で対応する必要があります。

根本解決とはなりませんが、1度のSQL更新でなるたけ2KBを超えないよう、更新対象のテーブル構造を分割しようと思っています。

■現在
plg_feature_page
 id
 main_content
 content1
 content2
 content3
 content4
 content5

 ↓ content1〜5 を別テーブルに外出しします。

■改修後
plg_feature_page
 id
 main_content

plg_feature_content
 id
 feature_id
 position
 content

ここで問題なのが、既に公開済みのプラグインなので、既存のデータを移行する必要があるということです。
plg_feature_page のデータを select で取得して、plg_feature_content に insert したいと思っています。

プラグインのマイグレーションでデータの移行は可能でしょうか?
可能なら方法をお教えいただきたいと思います。
468
投稿日時: 2018/9/7 10:27
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 1224
Re: プラグインアップデートで既存データを移行したい
私は実際にマイグレーションでデータの移行を行った事がないので、
正しいやり方か分かりませんが、
$this->connectionで、Doctrine DBALが使えるみたいです。

public function up(Schema $schema) {}の中で、
$result = $this->connection->fetchAssoc('SELECT id, name FROM table WHERE id = 1');
のような記述が使えるのではないでしょうか?

addSqlメソッドでinsert into selectをしても良いような気もしますが。


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

h_tanaka
投稿日時: 2018/9/7 17:34
対応状況: −−−
仙人
登録日: 2016/7/22
居住地: 愛媛県
投稿: 566
Re: プラグインアップデートで既存データを移行したい
468 様

ありがとうございます!
addSql で試してみます。


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

h_tanaka
投稿日時: 2018/9/7 18:08
対応状況: −−−
仙人
登録日: 2016/7/22
居住地: 愛媛県
投稿: 566
Re: プラグインアップデートで既存データを移行したい
次のように実装しましたが、うまくいきませんでした。。


class Version201809061627000 extends AbstractMigration
{
    public function up(Schema $schema)
    {
        $this->createTablePlgFeatureContent($schema);
        $this->copyContent($schema);
    }

    protected function createTablePlgFeatureContent(Schema $schema)
    {
        $table = $schema->createTable('plg_feature_content');
        $table->addColumn('id', 'integer', array(
            'autoincrement' => true,
        ));
        $table->addColumn('feature_id', 'integer', array(
            'notnull' => true,
            'unsigned' => false,
        ));
        $table->addColumn('position', 'smallint', array(
            'notnull' => true,
            'unsigned' => false,
        ));
        $table->addColumn('content', 'text', array(
            'notnull' => false,
            'default' => null,
        ));
        $table->setPrimaryKey(array('id'));

        $table->addForeignKeyConstraint(
            'plg_feature_page',
            array('feature_id'),
            array('id')
        );
    }

    protected function copyContent(Schema $schema)
    {
        $num = $this->connection->fetchAssoc('SELECT COUNT(*) FROM plg_feature_page');

        $id = 1;
        for ($i=1; $i<=$num; $i++) {
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 1, content1 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 2, content2 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 3, content3 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 4, content4 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 5, content5 FROM plg_feature_page WHERE id=".$i.";");
        }
    }

    public function down(Schema $schema)
    {
        if ($schema->hasTable('plg_feature_content')) {
            $schema->dropTable('plg_feature_content');
        }
        if ($schema->hasSequence('plg_feature_content_seq')) {
            $schema->dropSequence('plg_feature_content_seq');
        }
    }
}


コンソールから実行したら何も表示されずに終了しました。

$ /Applications/MAMP/bin/php/php5.6.10/bin/php app/console plugin:develop update --code=FeaturePage --path=FeaturePagePlugin110.tar.gz

管理画面からアップデートを試してみたら500エラーになりました。

500エラー?
実装ミスがあると500エラーになるのでしょうか。。

データベースの migration_FeaturePage に今回のマイグレーションバージョンのレコードが追加されていなかったので、コケているのは間違いないと思われます。


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

468
投稿日時: 2018/9/10 9:30
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 1224
Re: プラグインアップデートで既存データを移行したい
500エラーですので、エラーの内容はapacheのエラーログに残っているのではないでしょうか?
まずはどこでエラーが出ているか確認されるのが良いかと思います。

申し訳ないのですが、コードを見ても、
私もどこでエラーが発生しているのかは、分からないので...


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

h_tanaka
投稿日時: 2018/9/10 15:16
対応状況: −−−
仙人
登録日: 2016/7/22
居住地: 愛媛県
投稿: 566
Re: プラグインアップデートで既存データを移行したい
468 様

失礼いたしました。
先程再度試してみたところ、今度は500エラーになりました。
Apacheのエラーログを確認したところ、次のエラーメッセージが出力されていました。

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 137 bytes) in /Applications/MAMP/htdocs/test/eccube-3.0.16/app/Plugin/FeaturePage/Migration/Version201809061627000.php on line 56

データベースのテーブルから取得したものを別のテーブルに挿入するという処理をループして行っているため、途中でメモリオーバーになっている気がします。

app/Plugin/FeaturePage/Migration/Version201809061627000.php
    protected function copyContent(Schema $schema)
    {
        $num = $this->connection->fetchAssoc('SELECT COUNT(*) FROM plg_feature_page');

        $id = 1;
        for ($i=1; $i<=$num; $i++) {
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 1, content1 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 2, content2 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 3, content3 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 4, content4 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (id, feature_id, position, content) SELECT ".$id++.", id, 5, content5 FROM plg_feature_page WHERE id=".$i.";");    // ★ ここでエラー発生
        }
    }


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

468
投稿日時: 2018/9/11 10:48
対応状況: −−−
登録日: 2008/10/26
居住地:
投稿: 1224
Re: プラグインアップデートで既存データを移行したい
詳細は分かりませんが、addSqlはメモリを消費しやすいのですかね?

$idをループせずに、plg_feature_contentのidは、オートインクリメントに任せて、
$this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 1, content1 FROM plg_feature_page;");
$this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 2, content2 FROM plg_feature_page;");
$this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 3, content3 FROM plg_feature_page;");
$this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 4, content4 FROM plg_feature_page;");
$this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 5, content5 FROM plg_feature_page;");
5回のSQLで処理してもメモリオーバーが発生しますか?


----------------
株式会社シロハチ
■ECCUBE2系、3系構築カスタマイズご相談ください。
EC-CUBE3マニュアル
blog

h_tanaka
投稿日時: 2018/9/14 16:08
対応状況: −−−
仙人
登録日: 2016/7/22
居住地: 愛媛県
投稿: 566
Re: プラグインアップデートで既存データを移行したい
468 様

ありがとうございます。

id をオートインクリメントに変更して試してみましたが、同様のエラーになりました。

■エラーメッセージ
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /Applications/MAMP/htdocs/test/eccube-3.0.16/vendor/doctrine/migrations/lib/Doctrine/DBAL/Migrations/Version.php on line 168


app/Plugin/FeaturePage/Migration/Version201809061627000.php
    protected function copyContent(Schema $schema)
    {
        $num = $this->connection->fetchAssoc('SELECT COUNT(*) FROM plg_feature_page');

        $id = 1;
        for ($i=1; $i<=$num; $i++) {
            $this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 1, content1 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 2, content2 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 3, content3 FROM plg_feature_page WHERE id=".$i.";");
            $this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 4, content4 FROM plg_feature_page WHERE id=".$i.";");    // ★ ここでエラー発生
            $this->addSql("INSERT INTO plg_feature_content (feature_id, position, content) SELECT id, 5, content5 FROM plg_feature_page WHERE id=".$i.";");
        }
    }


あと、この方法はうまくいったとしても、PostgreSQL では動作しないと思われます。


----------------
EC-CUBE 《プラチナ》ランクパートナー
トエビス株式会社 田中 宏典
EC-CUBEの機能やデザインのカスタマイズ承ります。

スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ


 



ログイン


EC-CUBEペイメント

統計情報

総メンバー数は32,115名です
総投稿数は87,532件です

投稿数ランキング

1
seasoft
7331
2
AMUAMU
2712
3
nanasess
1774
4
yuh
1512
5
468
1224
6
red
1178
7
umebius
1007
8
fukap
907
9
shutta
827
10
tsuji
815
11 ramrun 789
12 karin 656
13
tao_s
651
14 sumida 641
15
homan
633
16 DELIGHT 571
17
h_tanaka
566
18
patapata
502
19
flealog
483
20 tonton 436


ネットショップの壺

EC-CUBEインテグレートパートナー

Copyright© LOCKON CO.,LTD. All Rights Reserved.