ken
ken

Reputation: 2662

How to create separate file to generate different table of database Flask-SqlAlchemy?

I using Flask-Restplus and SqlAlchemy to create my table and Api.The problem I facing is like below:

At first I have this user.py which having 2 table inside:

User.py

class User(db.Model):
    __tablename__ = "users_info"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.Integer, unique=True, nullable=True)
    device = db.relationship('Device', backref='user')
    # .. some other field here


class Device(db.Model):
    __tablename__ = "user_device"

    device_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    id = db.Column(db.Integer, db.ForeignKey(User.id))
    # .. some other field here

At this point,I using this 2 command below with manage.py to create the database,and have no problem.

python manage.py db migrate

python manage.py db upgrade

manage.py

import os
import unittest

from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from app import blueprint

from app.main import create_app, db

app = create_app(os.getenv('My_App') or 'dev')
app.register_blueprint(blueprint)

app.app_context().push()

manager = Manager(app)

migrate = Migrate(app, db)

manager.add_command('db', MigrateCommand)


@manager.command
def run():
    app.run()


if __name__ == '__main__':
    manager.run()

Now I want to create another file called product.py,which is a new table for the same database like below:

Product.py

from .. import db
from .model.user import User


class Product(db.Model):
    __tablename__ = "product"

    product_id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    product_name = db.Column(db.String)
    # plan here what you want in this table
    user_id = db.Column(db.Integer, db.ForeignKey(User.user_id))

As you can see Product class is having relationship with User with the foreignKey.

Result:

But I use the same command above to migrate again,the result is look like this :

INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.env] No changes in schema detected.

It seems like didn't detect the new table from my new file.

My Question:

How to create separate file to generate different table of database?

Upvotes: 1

Views: 1812

Answers (1)

Miguel Grinberg
Miguel Grinberg

Reputation: 67509

I think the problem is that the models aren't being imported, which means that SQLAlchemy and Alembic do not know about them.

This is counterintuitive to some people, but SQLAlchemy uses introspection to find out what models are defined, so in many cases the solution to your problem is to just import the models in your main script, even if you don't need to use them. Importing them will make them visible to SQLAlchemy and Alembic, and from there everything will work well.

In your case, you just need to add something like the following in manage.py:

from model.user import User
from model.product import Product

If this results in import errors due to circular dependencies, you may want to move the imports down below all other imports. If you define your db instance in the same script, then you want these imports below the line that defines the database, since obviously the database needs to be defined first.

Upvotes: 3

Related Questions