web-dev-qa-db-ja.com

SQLAlchemyはMySQLの「テキスト」にどの列タイプを使用しますか?

私の全体的なユースケースは、いくつかの大きなデータを生テキストとして多少データベースに依存しない(少なくともPostgresとMySQLをサポートする)ストアを作成できるかどうかを判断しようとしています(おおよそ500MBを理論上の上限と考えてください)。 この回答 MySQLの文字列/テキストタイプに基づいて、LONGTEXT列タイプのみが要件を満たすことができるようです。私はSQLAlchemyを使用しています。SQLAlchemyは、 Text カラムタイプが可変長文字列用であると主張していますが、通常はデータベースのCLOBまたはTEXTタイプにマップします。 MySQLにはCLOB型はありませんが(BLOBがあります)、TEXT型は私のニーズには不十分です。

したがって、SQLAlchemyはMySQLの「テキスト」にどの列タイプを使用しますか?

9
augray

SQLAlchemyはLONG​​TEXTをサポートしているようです:

$ 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など)を使用したい場合はどうでしょうか。

10
Bill Karwin

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     |
9
tandy