Flask仮想データの作成
Flask開発では、ページング機能の実装など、大量のデータを含むデータベースが必要になることが多い.データベース・レコードを手動で追加するのは時間がかかり、面倒なので、自動化スキームを使用することが望ましい.複数のPythonパッケージを使用して仮想情報を生成できます.ここで、機能が比較的完備しているForgeryPyはpipを使用してインストールできます.
開発過程でしか使用されていないため、厳密にはForgeryPyはこのプログラムの依存ではありません.本番環境の依存性と開発環境の依存性を区別するために、ファイルrequirements.txtをrequirementsフォルダに変更し、それぞれ異なる環境での依存性を保存できます.この新しいフォルダでは、dev.txtファイルを作成し、開発中に必要な依存をリストし、prod.txtファイルを作成し、本番環境に必要な依存をリストできます.
2つの環境で必要な依存度の大部分は同じであるため、dev.txtおよびprod.txtで-rパラメータを使用してインポートするcommon.txtファイルを作成できます.
<span style="font-size:18px;">(venv) $ pip install forgerypy</span>
開発過程でしか使用されていないため、厳密にはForgeryPyはこのプログラムの依存ではありません.本番環境の依存性と開発環境の依存性を区別するために、ファイルrequirements.txtをrequirementsフォルダに変更し、それぞれ異なる環境での依存性を保存できます.この新しいフォルダでは、dev.txtファイルを作成し、開発中に必要な依存をリストし、prod.txtファイルを作成し、本番環境に必要な依存をリストできます.
2つの環境で必要な依存度の大部分は同じであるため、dev.txtおよびprod.txtで-rパラメータを使用してインポートするcommon.txtファイルを作成できます.
requirements/common.txt
Flask==0.10.1
Flask-Bootstrap==3.0.3.1
Flask-HTTPAuth==2.7.0
Flask-Login==0.3.1
Flask-Mail==0.9.0
Flask-Migrate==1.1.0
Flask-Moment==0.2.1
Flask-PageDown==0.1.4
Flask-SQLAlchemy==1.0
Flask-Script==0.6.6
Flask-WTF==0.9.4
Jinja2==2.7.1
Mako==0.9.1
Markdown==2.3.1
MarkupSafe==0.18
SQLAlchemy==0.9.9
WTForms==1.0.5
Werkzeug==0.10.4
alembic==0.6.2
bleach==1.4.0
blinker==1.3
html5lib==1.0b3
itsdangerous==0.23
six==1.4.1
requirements/dev.txt:
-r common.txt
ForgeryPy==0.1
requirements/prod.txt:
-r common.txt
如下展示了添加到 User 模型类方法,用来生成虚拟数据。
class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True, index=True) username = db.Column(db.String(64), unique=True, index=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) password_hash = db.Column(db.String(128)) confirmed = db.Column(db.Boolean, default=False) name = db.Column(db.String(64)) location = db.Column(db.String(64)) about_me = db.Column(db.Text()) member_since = db.Column(db.DateTime(), default=datetime.utcnow) last_seen = db.Column(db.DateTime(), default=datetime.utcnow) avatar_hash = db.Column(db.String(32)) posts = db.relationship('Post', backref='author', lazy='dynamic') followed = db.relationship('Follow', foreign_keys=[Follow.follower_id], backref=db.backref('follower', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') followers = db.relationship('Follow', foreign_keys=[Follow.followed_id], backref=db.backref('followed', lazy='joined'), lazy='dynamic', cascade='all, delete-orphan') comments = db.relationship('Comment', backref='author', lazy='dynamic') <strong>@staticmethod def generate_fake(count=100): from sqlalchemy.exc import IntegrityError from random import seed import forgery_py seed() for i in range(count): u = User(email=forgery_py.internet.email_address(), username=forgery_py.internet.user_name(True), password=forgery_py.lorem_ipsum.word(), confirmed=True, name=forgery_py.name.full_name(), location=forgery_py.address.city(), about_me=forgery_py.lorem_ipsum.sentence(), member_since=forgery_py.date.date(True)) db.session.add(u) try: db.session.commit() except IntegrityError: db.session.rollback()</strong>
仮想データを生成するためにPostモデルクラスに追加する方法を以下に示す.class Post(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer, primary_key=True) body = db.Column(db.Text) body_html = db.Column(db.Text) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) comments = db.relationship('Comment', backref='post', lazy='dynamic') <strong>@staticmethod def generate_fake(count=100): from random import seed, randint import forgery_py seed() user_count = User.query.count() for i in range(count): u = User.query.offset(randint(0, user_count - 1)).first() p = Post(body=forgery_py.lorem_ipsum.sentences(randint(1, 5)), timestamp=forgery_py.date.date(True), author=u) db.session.add(p) db.session.commit()</strong>
これらの仮想オブジェクトの属性はForgeryPyのランダム情報生成器によって生成され、名前、電子メールアドレス、文などの属性は本物のように見えます.ユーザーのEメールアドレスとユーザー名は一意でなければなりませんが、ForgeryPyはこれらの情報をランダムに生成するため、重複するリスクがあります.このような不可能な状況が発生した場合、データベース・セッションのコミット時にIntegratyError例外が放出されます.この例外の処理は、操作を続行する前にセッションをロールバックすることです.ループ中に重複コンテンツが生成されると、ユーザーはデータベースに書き込まれないため、生成される仮想ユーザーの総数は予想より少なくなる可能性があります.ランダムに文章を生成するときは、各文章にランダムにユーザーを指定します.このためoffset()クエリーフィルタを使用します.このフィルタは、パラメータで指定したレコードの数をスキップします.ランダムなオフセット値を設定してfirst()メソッドを呼び出すことで、毎回異なるランダムユーザを得ることができます.
新しく追加された方法では、Python shellで多くの仮想ユーザーと記事を簡単に生成できます.(venv) $ python manage.py shell >>> User.generate_fake(100) >>> Post.generate_fake(100)