3、生成虚拟数据
为了方便编写程序前台和后台功能,我们在创建数据库模型后就编写生成虚拟数据的函数。
1)管理员
用于生成虚拟管理员信息的fake_admin()函数如下所示:
personalBlog/fakes.py: 生成虚拟管理员信息
from personalBlog.models import Admin from personalBlog.extensions import db def fake_admin(): admin = Admin( username = 'admin', blog_title = 'PersonalBlog', blog_sub_title = "It is a good sample to practice flask", name = 'Xia Xiaoxu', about = 'Great, i am very happpy to see this book to learn flask!' ) admin.set_password('persoanlBlog') db.session.add(admin) db.session.commit()
2)分类
用于生成虚拟分类的fake_categories()函数如下所示:
personalBlog/fakes.py : 创建虚拟分类
from faker import Faker from personalBlog.models import Category from personalBlog.extensions import db def fake_categories(name = 10): category = Category(name = 'Default') db.session.add(category) for i in range(count): category = Category(name = fake.word()) db.session.add(category) try: db.session.commit() except: db.session.roolback()
这个函数首先会创建一个默认分类,默认分类是创建文章时默认设置的分类。然后依次生成包含随机名称的虚拟分类。
和文章不同的是,分类的名称要求不能重复,如果随机生成的分类名和已创建的分类重名,就会导致数据库出错,抛出salalchemy.exc.IntegrityError异常。在这种情况下,我们可以使用try…except…语句来捕捉异常,在try子句中调用db.session.commit()提交数据库会话,如果发生sqlalchemy.exc.IntegrityError异常,就调用db.session.roolback()方法进行回滚操作。
3)文章
用于生成虚拟文章数据的fake_posts()函数如下所示:
personalBlog/fakes.py : 生成虚拟文章
from faker import Faker from personalBlog.models import Post from personalBlog.extensions import db fake = Faker() def fake_posts(count = 50): for i in range(count): post = Post( title = fake.sentence(), body = fake.text(2000), category = Category.query.get(random.randint(1, Category.query.count())), timestamp = fake.date_time_this_year() ) db.session.add(post) db.session.commit()
默认生成50篇文章,每一篇文章均指定了一个随机分类。随机分类使用get()查询方法获取,传入的主键值为1到所有分类数量数据之间的随机值。
4)评论
用于生成虚拟评论的fake_comments()函数如下所示:
personalBlog/fakes.py : 生成虚拟评论
from faker import Faker from personalBlog.models import Comment from personalBlog.extensions import db fake = Faker() def fake_comments(count = 500): for i in range(count): comment = Comment( author = fake.name(), email = fake.email(), site = fake.url(), body = fake.sentence(), timestamp = fake.date_time_this_year(), reviewed = True, post = Post.query.get(random.randint(1, Post.query.count())) ) db.session.add(comment) salt = int(count * 0.1) for i in range(salt): # 未审核评论 comment = Comment( author = fake.name(), email = fake.email(), site = fake.url(), body = fake.sentence(), timestamp = fake.date_time_this_year(), reviewed = False, post = Post.query.get(random.randint(1, Post.query.count())) ) db.session.add(comment) # 管理员发表的评论 comment = Comment( author = 'Sam Xia', email = 'sam@163.com', site = 'example.com', body = fake.sentence(), timestamp = fake.date_time_this_year(), from_admin = True, reviewed = True, post = Post.query.get(random.randint(1, Post.query.count())) ) db.session.add(comment) db.session.commit() # 回复 for i in range(salt): comment = Comment( author = fake.name(), email = fake.email(), site = fake.url(), body = fake.sentence(), timestamp = fake.date_time_this_year(), reviewed = True, replied = Comment.query.get(random.randint(1, Comment.query.count())), post = Post.query.get(random.randint(1, Post.query.count())) ) db.session.add(comment) db.session.commit()
默认随机生成500条评论,另外再额外添加50条(count * 0.1)为审核评论、50条管理员评论和50条回复。
5)创建生成虚拟数据的命令
我们创建一个forge()函数来整合上述函数,如下所示:
personalBlog/personalBlog/__init__.py: 晚上register_commands()函数
def register_commands(app): @app.cli.command() @click.option('--category', default = 10, help = 'Quantity of categories, default is 10.') @click.option('--post', default=50, help = 'Quantity of posts, default is 50.') @click.option('--comment', default=500, help = 'Quantity of comments, default is 500.') def forge(category, post, comment): """Generates the fake categories, posts, and comments.""" from personalBlog.fakes import fake_admin, fake_categories, fake_posts, fake_comments db.drop_all() db.create_all() click.echo('Generating the administrator...') fake_admin() click.echo('Generating %d categories...' % category) fake_categories(category) click.echo('Generating %d posts...' % post) fake_posts(post) click.echo('Generating %d comments...' % comment) fake_comments(comment) click.echo('Done.')
为了正常生成数据,这里的生成顺序必须是管理员-> 分类 -> 文章 -> 评论。
虽然默认的数量能够满足常规需求,但是函数中使用click提供的option装饰器添加了对自定义数量支持。在这个函数中,为了更全面地生成虚拟数据,首先会删除并重建数据库表。 使用下面的命令,我们就会生成完整的虚拟博客数据:
flask forge:
通过添加命令选项生成20个分类、100片虚拟文章和1000个评论: