How do I seed a flask sql-alchemy database

12.4k views Asked by At

I am new at python, I just learnt how to create an api using flask restless and flask sql-alchemy. I however would like to seed the database with random values. How do I achieve this? Please help. Here is the api code...

import flask
import flask.ext.sqlalchemy
import flask.ext.restless
import datetime

DATABASE = 'sqlite:///tmp/test.db'

#Create the Flask application and the FLask-SQLALchemy object
app = flask.Flask(__name__)
app.config ['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] =  DATABASE
db = flask.ext.sqlalchemy.SQLAlchemy(app)

#create Flask-SQLAlchemy models
class TodoItem(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    todo = db.Column(db.Unicode)
    priority = db.Column(db.SmallInteger)
    due_date = db.Column(db.Date)

#Create database tables
db.create_all()

#Create Flask restless api manager
manager = flask.ext.restless.APIManager(app, flask_sqlalchemy_db = db)

#Create api end points
manager.create_api(TodoItem, methods = ['GET','POST','DELETE','PUT'], results_per_page = 20)

#Start flask loop
app.run()
2

There are 2 answers

2
Han Lazarus On

From another newbie, the forgerypy and forgerypy3 libraries are available for this purpose (though they look like they haven't been touched in a bit).

A simple example of how to use them by adding them to your model:

class TodoItem(db.Model):

    ....

    @staticmethod
    def generate_fake_data(records=10):
        import forgery_py
        from random import randint
        for record in records:
            todo = TodoItem(todo=forgery_py.lorem_ipsum.word(),
                            due_date=forgery_py.date.date(),
                            priority=randint(1,4))
            db.session.add(todo)
        try:
            db.session.commit()
        except:
            db.session.rollback()

You would then call the generate_fake_data method in a shell session.

And Miguel Grinberg's Flask Web Development (the O'Reilly book, not blog) chapter 11 is a good resource for this.

0
Mike On

I had a similar question and did some research, found something that worked.

The pattern I am seeing is based on registering a Flask CLI custom command, something like: flask seed.

This would look like this given your example. First, import the following into your api code file (let's say you have it named server.py):

from flask.cli import with_appcontext

(I see you do import flask but I would just add you should change these to from flask import what_you_need)

Next, create a function that does the seeding for your project:

@with_appcontext
def seed():
   """Seed the database."""
   todo1 = TodoItem(...).save()
   todo2 = TodoItem(...).save()
   todo3 = TodoItem(...).save()

Finally, register these command with your flask application:

def register_commands(app):
    """Register CLI commands."""
    app.cli.add_command(seed)

After you've configured you're application, make sure you call register_commands to register the commands:

register_commands(app)

At this point, you should be able to run: flask seed. You can add more functions (maybe a flask reset) using the same pattern.