title: How can I initialize a database table with Flask / SQLalchemy / Alembic?
body: <p>I have a database table of languages with relatively static content:</p>
  
  <pre><code>from flask_sqlalchemy import SQLAlchemy
  
  db = SQLAlchemy()
  
  class Language(db.Model):
      __tablename__ = 'languages'
  
      # Fields
      code = db.Column(db.String(2), primary_key=True)
      name = db.Column(db.String(40))
      native = db.Column(db.String(60))
      rtl = db.Column(db.Boolean())  # right to left
  </code></pre>
  
  <p>The <a href="https://github.com/MartinThoma/mpu/blob/master/mpu/data/laguages.csv.gz" rel="noreferrer">data is in a CSV</a>. I want to insert it into the database. Can I do this with alembic?</p>
  
  <p>I initialize all tables (the structure, not the data) with</p>
  
  <pre><code>$ flask db init
  $ flask db migrate
  $ flask db update
  </code></pre>
  
  <p>(Side-question: Should this be in the database in the first place, or maybe rather as a CSV in the code? I use it in a CMS to allow users to specify which languages the speak / which language the page is they've created.)</p>
  
  <h2>My Try</h2>
  
  <p>Providing an endpoint which adds the stuff when called:</p>
  
  <pre><code>@app.route('/secret_init_languages')
  def db_init_languages():
      from mpu.string import str2bool
      import csv
      path = resource_filename('my_package', 'static/languages.csv')
      nb_languages = 0
      with open(path, 'rt', newline='') as csvfile:
          csvreader = csv.reader(csvfile, delimiter=',')
          next(csvreader, None)  # skip the headers
          for row in csvreader:
              lang = Language(code=row[0],
                              name=row[1],
                              native=row[2],
                              rtl=str2bool(row[3]))
              db.session.add(lang)
              nb_languages += 1
          db.session.commit()
      return 'Added {} languages'.format(nb_languages)
  </code></pre>
  
  <p>Drawbacks of this solution:</p>
  
  <ul>
  <li>I have an endpoint which should only be called once</li>
  <li>I could forget to run it</li>
  </ul>