Mimesisを使用したダミーデータの生成:パートII

画像






Pythonプログラミング言語のライブラリであるMimesisを使用してダミーデータを生成する方法に関する記事を以前に公開しました。 あなたが読んでいる記事は前の記事の続きです。なぜなら、私たちはライブラリを扱う基本を教えないからです。 記事を見逃したり、読むのが面倒だったり、単にしたくない場合は、読者は既にライブラリの基本に精通していることを前提としているため、おそらく今すぐ読みたいと思うでしょう。 この記事のこの部分では、ライブラリの便利な機能について、ベストプラクティスについて説明します。







レマルク



まず、Mimesisは特定のデータベースまたはORMで使用するために開発されたものではないことに注意してください。 ライブラリが解決する主なタスクは、有効なデータの提供です。 このため、ライブラリを操作するための厳密なルールはありませんが、テスト環境を適切に保ち、プロジェクトでのエントロピーの増加を防ぐための推奨事項があります。 推奨事項は非常にシンプルで、Pythonの精神と完全に一致しています(そうでない場合は、コメントをお待ちしています)。







構造化



ライブラリは特定のデータベースまたはORMでの使用を目的としていないという上記のステートメントとは異なり、テストデータの必要性は、ほとんどの場合、データベースで何らかの操作(ほとんどの場合CRUD)を実行するWebアプリケーションでのみ発生します。 Webアプリケーションのテストデータ生成を整理するための推奨事項がいくつかあります。







データを生成してデータベースに書き込む関数は、前の記事の_bootstrap()



メソッドの例に従って、モデルの近くに保持する必要があります。 これは、モデルの構造が変更され、新しいフィールドを追加する必要がある場合にファイルの回り込みを回避するためです。 前の記事のPatient()



モデルは、このアイデアをよく示しています。







 class Patient(db.Model): id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(120), unique=True) phone_number = db.Column(db.String(25)) full_name = db.Column(db.String(100)) weight = db.Column(db.String(64)) height = db.Column(db.String(64)) blood_type = db.Column(db.String(64)) age = db.Column(db.Integer) def __init__(self, **kwargs): super(Patient, self).__init__(**kwargs) @staticmethod def _bootstrap(count=500, locale='en', gender): from mimesis import Personal person = Personal(locale) for _ in range(count): patient = Patient( email=person.email(), phone_number=person.telephone(), full_name=person.full_name(gender=gender), age=person.age(minimum=18, maximum=45), weight=person.weight(), height=person.height(), blood_type=person.blood_type() ) db.session.add(patient) try: db.session.commit() except IntegrityError: db.session.rollback()
      
      





上記の例は、SQLAlchemyを使用するFlaskアプリケーションモデルであることに注意してください。 他のフレームワークを使用して作成されたアプリケーションのダミーデータジェネレーターの構成も同様です。







オブジェクトを作成する



アプリケーションが特定の言語のデータのみを想定している場合は、プロバイダクラスの複数のインスタンスを個別に生成するのではなく、単一のオブジェクトを介してすべてのプロバイダクラスへのアクセスを提供するGeneric()



クラスを使用するのが最善です。 Generic()



を使用すると、余分なコード行を取り除くことができます。







正しい:







 >>> from mimesis import Generic >>> generic = Generic('ru') >>> generic.personal.username() 'sherley3354' >>> generic.datetime.date() '14-05-2007'
      
      





無効:







 >>> from mimesis import Personal, Datetime, Text, Code >>> personal = Personal('ru') >>> datetime = Datetime('ru') >>> text = Text('ru') >>> code = Code('ru')
      
      





同時に、それは本当です:







 >>> from mimesis import Personal >>> p_en = Personal('en') >>> p_sv = Personal('sv') >>> # ...
      
      





つまり、インポートされたインポートクラスが持っているデータのみに制限されている場合にのみ、プロバイダークラスを個別にインポートすることは意味があります。







データベースへのデータの書き込み



データを生成してデータベースに書き込む必要がある場合は、一度に600k



ではなくバッチでデータを生成することを強くお勧めします。 データベース、ORMなどの一部にいくつかの制限がある可能性があることを覚えておく必要があります。 記録用に生成されるデータのチャンクが小さいほど、記録が高速になります。







良い:







 >>> User()._bootstrap(count=2000, locale='de')
      
      





非常に悪い:







 >>> User()._bootstrap(count=600000, locale='de')
      
      





画像をアップロードする



Internet()



クラスには、画像へのリンクを生成するいくつかのメソッドがあります。 テストでは、リモートリソースにあるイメージへのリンクで十分ですが、ランダムイメージのセットをローカルに保持したい場合は、 utils



モジュールからdownload_image()



関数を使用して、 Internet()



クラスの対応するメソッドで生成されたイメージをダウンロードできます:







 >>> from mimesis.utils import download_image >>> from mimesis import Internet >>> img_url = Internet().stock_image(category='food', width=1920, height=1080) >>> download_image(url=img_url, save_path='/some/path/')
      
      





ユーザープロバイダー



ライブラリは大量のデータをサポートしており、ほとんどの場合はそれで十分ですが、より具体的なデータを使用して独自のプロバイダーを作成する場合は、この機能がサポートされ、次のように実行されます。







 >>> from mimesis import Generic >>> generic = Generic('en') >>> class SomeProvider(): ... class Meta: ... name = "some_provider" ... ... @staticmethod ... def one(): ... return 1 >>> class Another(): ... @staticmethod ... def bye(): ... return "Bye!" >>> generic.add_provider(SomeProvider) >>> generic.add_provider(Another) >>> # ... >>> generic.some_provider.one() 1 >>> generic.another.bye() 'Bye!'
      
      





コメントなしですべてがシンプルで明確なので、1つだけポイントを明確にしますMeta



クラスのname



属性は、ユーザー提供のプロバイダークラスのメソッドにアクセスするクラスの名前です。 デフォルトでは、クラス名は小文字のクラス名です。







組み込みプロバイダー



特定の言語が公用語であるほとんどの国には、それらの国にのみ固有のデータがあります。 たとえば、ブラジルのCPF



、米国のSSN



。 この種のデータは、選択された言語標準に関係なく、すべてのオブジェクトに存在する不便さや混乱を引き起こす可能性があります(少なくとも厄介です)。 どのように見えるかの例を見ると、自分で確認できます(コードは機能しません)。







 >>> from mimesis import Personal >>> person = Personal('ru') >>> person.ssn() >>> person.cpf()
      
      





本当に悪いように見えることに誰もが同意すると思います。 完璧主義者として、ブラジルのCPFが「極」にmimesis.builtins



ないようにしました。このため、この種のmimesis.builtins



固有のデータを提供するプロバイダークラスは、すべての言語の共通構造を維持するために別のmimesis.builtins



mimesis.builtins



)に配置されmimesis.builtins



クラスとそのオブジェクト。







だからそれは動作します:







 >>> from mimesis import Generic >>> from mimesis.builtins import BrazilSpecProvider >>> generic = Generic('pt-br') >>> class BrazilProvider(BrazilSpecProvider): ... ... class Meta: ... name = "brazil_provider" ... >>> generic.add_provider(BrazilProvider) >>> generic.brazil_provider.cpf() '696.441.186-00'
      
      





一般に、 Generic()



オブジェクトにインラインクラスを追加する必要はありません。 例では、これは、組み込みプロバイダークラスをGeneric()



オブジェクトに追加することが適切な場合を示すためにのみ行われました。 以下に示すように、直接使用できます。







 >>> from mimesis.builtins import RussiaSpecProvider >>> ru = RussiaSpecProvider() >>> ru.patronymic(gender='female') '' >>> ru.patronymic(gender='male') ''
      
      





どのデータが最も頻繁に作業を必要としますか? ライブラリで見逃されたものと、すぐに追加する必要があるものは何ですか? 私たちはあなたの願い/勧告/コメントを聞いて非常にうれしいです。







プロジェクトへのリンク: こちら

ドキュメントへのリンク: こちら

記事の最初の部分: here







それは私、友人のためのすべてです。 あなたの幸運を祈ります。








All Articles