壊れたマイグレーションの修復

□未翻訳

□翻訳中

■翻訳完了(細田謙二)

■レビュー(Omi Chiba)

壊れたマイグレーションの修復

マイグレーションには2つの一般的な問題があり、それらを修復する方法があります。

There are two common problems with migrations and there are ways to recover from them.

1つの問題は、SQLite固有のものです。SQLiteは、カラムの型を強制せず、また、カラムを削除することができません。したがって、文字列型のカラムを持っていて、それを削除した場合、それは実際には削除されません。異 なる型のカラムを再び加えようとした場合(たとえばdatetime)、(実践的にはごみとなる)文字列が含まれるデータベース・カラムを作ってしまうこ とになります。web2pyはこれに対してエラーを出しません。なぜなら、レコードを取り出して失敗するまでは、データベースに何が入っているか知らない からです。

One problem is specific with SQLite. SQLite does not enforce column types and cannot drop columns. This means that if you have a column of type string and you remove it, it is not really removed. If you add the column again with a different type (for example datetime) you end up with a datetime column that contains strings (junk for practical purposes). web2py does not complain about this because does not know what is in the database, until it tries to retrieve records and it fails.

もしweb2pyが、レコード選択時にgluon.sql.parse関数においてエラーを返す場合、これは、上記の問題によるカラム内の壊れたデータ、に関する問題になります。

If web2py returns an error in the gluon.sql.parse function when selecting records, this is the problem: corrupted data in a column because of the above issue.

解決方法は、テーブルのすべてのレコードを更新し、問題となっているカラムの値をNoneに更新することです。

The solution consists in updating all records of the table and updating the values in the column in question with None.

もう1つの問題は、より汎用的ですが、よくMySQLにおいて見られるものです。MySQLは、トランザクション中に複数のALTER TABLEを許可しません。これは、web2pyが、複雑なトランザクションを小さなもの(一度に1つのALTER TABLE)に分解しなければならず、一つ一つコミットしなければならないことを意味します。したがって、複雑なトランザクションの一部がコミットされ、別の部分が失敗して、web2pyを壊れた状態にしてしまう可能性があります。なぜトランザクションの一部が失敗するでしょうか?なぜなら、たとえば、テーブルを変更し、文字列カラムを日付カラムに変更しようとしたとき、web2pyがそれらのデータを変換しようとするが、そのデータが変換することができない場合があるからです。web2pyはどうなるのでしょうか?テーブル構造がデータベースに実際に保存したものは正確に何なのか、ということについて混乱してしまいます。

The other problem is more generic but typical with MySQL. MySQL does not allow more than one ALTER TABLE in a transaction. This means that web2py must break complex transactions into smaller ones (one ALTER TABLE at the time) and commit one piece at the time. It is therefore possible that part of a complex transaction gets committed and one part fails leaving web2py in a corrupted state. Why would part of a transaction fail? Because, for example, it involves altering a table and converting a string column into a datetime column, web2py tries to convert the data, but the data cannot be converted. What happens to web2py? It gets confused about what exactly is the table structure actually stored in the database.

解決策は、すべてのテーブルに対するmigrationを無効にし、次のように、fake migrationを有効にすることです:

The solution consists of disabling migrations for all tables and enabling fake migrations:

1.

db.define_table(....,migrate=False,fake_migrate=True)

これにより、テーブルに関するweb2pyのメタデータは、テーブル定義に従って再構築されます。複数のテーブル定義を行い、(マイグレーションが失敗する前のものと後のものの)どれが機能するか試してみてください。一旦成功した後は、fake_migrate=True属性を削除してください。

This will rebuild web2py metadata about the table according to the table definition. Try multiple table definitions to see which one works (the one before the failed migration and the one after the failed migration). Once successful remove the fake_migrate=True attribute.

マイグレーション問題を修復しようとする前に、"applications/yourapp/databases/*.table"ファイルのコピーをとっておくのが賢明です。

Before attempting to fix migration problems it is prudent to make a copy of "applications/yourapp/databases/*.table" files.