私の全体的なユースケースは、いくつかの大きなデータを生テキストとして多少データベースに依存しない(少なくともPostgresとMySQLをサポートする)ストアを作成できるかどうかを判断しようとしています(おおよそ500MBを理論上の上限と考えてください)。 この回答 MySQLの文字列/テキストタイプに基づいて、LONGTEXT列タイプのみが要件を満たすことができるようです。私はSQLAlchemyを使用しています。SQLAlchemyは、 Text カラムタイプが可変長文字列用であると主張していますが、通常はデータベースのCLOBまたはTEXTタイプにマップします。 MySQLにはCLOB型はありませんが(BLOBがあります)、TEXT型は私のニーズには不十分です。
したがって、SQLAlchemyはMySQLの「テキスト」にどの列タイプを使用しますか?
SQLAlchemyはLONGTEXTをサポートしているようです:
$ python
Python 2.7.13 (default, Sep 29 2017, 15:31:18)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.37)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from sqlalchemy.dialects.mysql import LONGTEXT
>>>
ベンダー固有のタイプの使用方法については、こちらをご覧ください。 http://docs.sqlalchemy.org/en/latest/core/type_basics.html#vendor-specific-types
価値のあるものとしては、完全にブランドに中立なデータベースレイヤーを開発しようとするのは難しく、努力する価値はほとんどありません。私は数年前にZend Framework 1.0に取り組み、そのフレームワークでサポートされているすべてのSQLデータベース用の汎用ユニットテストスイートを作成しようとしました。 ANSI/ISO SQL標準をサポートすると主張しているにもかかわらず、SQLのすべての実装で同じ方法でサポートされているデータ型はほとんどありません。
最終的に、データレイヤー用に独自のクラス階層を開発し、データベース固有のアダプターごとにコードをわずかに実装する必要があります。
更新:ニュースは私たちが考えるよりも良いと思います。私はこのテストを試しました:
t2 = Table('t2', metadata,
Column('id', Integer, primary_key=True),
Column('t1', String(64000)),
Column('t2', String(16000000)),
Column('t3', String(4294000000)),
Column('t4', Text)
)
metadata.create_all(engine)
次に、MySQLデータベースで何が作成されるかを確認しました。
mysql> show create table t2;
CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`t1` mediumtext,
`t2` longtext,
`t3` longtext,
`t4` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
そのため、SQLAlchemyの一般的なString
データ型を、多かれ少なかれ適切なMySQLデータ型にマップします。
予想よりも大きなデータ型を使用したことは、私にとって驚くことではありません。 MEDIUMTEXT
は、bytesではなくbytesで16MBをサポートします。私のデフォルトの文字セットはマルチバイトutfmb4であるため、MEDIUMTEXT
の最大長は実際には2 ^ 24文字よりはるかに短くなっています。そのため、LONGTEXT
にアップグレードする必要がありました。もちろん、2 ^ 32文字もLONGTEXT
には収まりませんが、SQLAlchemyはとにかく列を作成するつもりであると想定しているようです。
実装に中立なコードを完全に実行することはまだ難しいと思います。たとえば、ストレージエンジンのテーブルオプションのようなMySQLの機能を使用したり、一般的な同等物のない特定のデータ型(ENUM
など)を使用したい場合はどうでしょうか。
SQLAlchemy 1.2.7では、Textデータタイプは、入力した長さに応じてMySQLタイプ「text」または「longtext」にマッピングされます。
body_html = Column(Text())
body_plain = Column(Text(4294000000))
MySQLで次を作成します。
| Field | Type |
+-----------------+--------------+
| body_html | text |
| body_plain | longtext |