How do I manage django and flask apps using the same database model?

I have two repositories written in flask and django.
These projects use a database model that is written in SQLAlchemy in flask and written in Django ORM.
When I write a migration script in flask as alembic, how can a django project migrate using this script?

I am also thinking about Django with SQLAlchemy. But I cannot find Django projects using SQLAlchemy. It is a bad idea? Thank.

+3


source to share


2 answers


In our workplace we use both django and flask on the same site. The reason for this is that the django admin and model system is very quick to write the code and it serves as our admin interface (staff only). On the other hand, it is much easier to write an interface in a flask, as each page can be as simple as a single python function and a Jinja2 template. Flask forms require an additional model model class (easy to write) that defines all the fields in the form and a second SQLAlchemy model if the form responses are to be stored in a SQL database. If you want to write the same form in django, in the simplest case, you don't write a form model, since the django framework implicitly generates it from the sql model. However, it is even faster to write "regular" pages in a bulb.

As for making the two games good together, the way it ends up we write the django model first, since database management and sql schema migrations are baked into django. We then use a SQLAlchemy function called "reflection" that reads the sql database and generates an sql model from the schema. This way, when we make changes to the django model, we run the manage.py migration (which deploys the schema changes to the sql database) and the SQLAlchemy models automatically reflect the new schema without having to touch the Flask-SQLAlchemy model.Here is an example that includes some foreign key stuff and some timestamps that are automatically updated when you use the ORM to save the model. I included them because they are both common use cases,and both require additional code.

Django model:

from django.db import models

class DjangoModel(models.Model):
    field1 = models.CharField(max_length=10)
    field2 = models.IntegerField()
    field3 = models.DateTimeField()
    # We frequently use timestamps like this that the ORM updates automatically on creation and modification respectively.
    created_timestamp = models.DateTimeField(auto_now_add=True)
    modified_timestamp = models.DateTimeField(auto_now=True)
    related = models.ForeignKey(SomeOtherDjangoModel, related_name='related_backref')
    class Meta:
        db_table = 'sql_table_name'

      

Flask-SQLAlchemy model:

from flask import current_app
from flask_sqlalchemy import SQLAlchemy
import datetime

# The next three lines should be in your application.py ideally.
db = SQLAlchemy()
db.init_app(current_app)
db.Model.metadata.reflect(db.engine)

class FlaskSQLAlchemyModel(db.Model):
    # All 6 fields from the django model and the implicit 'id' field django
    # adds to its models will get reflected automatically the way this model
    # is coded. The created_timestamp and modified_timestamp fields require
    # special code for Flask-SQLAlchemy to update them automatically when
    # you save a model instance. Relationships must be defined manually in
    # Flask-SQLAlchemy, so there code for that, too.
    __table__ = db.Table('sql_table_name', db.Model.metadata,
            # You'll need to "override" the timestamp fields to get flask-sqlalchemy to update them automatically on creation and modification respectively.
            db.Column('created_timestamp', db.DateTime, default=datetime.datetime.now),
            db.Column('modified_timestamp', db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now),
            autoload=True,
            extend_existing=True,
            autoload_with=db.engine,
        )
    # You need to do model relationships manually in SQLAlchemy...
    related = db.relationship(SomeOtherFlaskSQLAlchemyModel, backref=db.backref('related_backref', lazy='dynamic'))

      

The caveat for defining Flask-SQLAlchemy models this way is that they depend on the SQL database. Flask-SQLAlchemy and its object db

must be set up correctly before trying to import the .py file that contains the model, otherwise you will be rewarded with some nasty import errors. If you put the definition db

in the same file as the model and it is initialized like this:

from flask import current_app
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
db.init_app(current_app)

      



Then you will need to do an import like this:

with app.app_context():
    import module_with_flask_sqlalchemy_model

      

Of course, app

must have the config loaded for Flask-SQLAlchemy, or that won't work. It's usually best to just have a model file from application import db

and have application.py done from my_models import *

after it has db

been configured.

Once configured correctly, the Flask-SQLAlchemy model will be equivalent to the Flask-SQLAlchemy model defined as follows:

from flask import current_app
from flask_sqlalchemy import SQLAlchemy
import datetime

db = SQLAlchemy()
db.init_app(current_app)

class FlaskSQLAlchemyModel(db.Model):
    __tablename__ = 'sql_table_name'
    id = db.Column(db.Integer, primary_key=True)
    field1 = db.Column(db.String(10))
    field2 = db.Column(db.Integer)
    field3 = db.Column(db.DateTime)
    created_timestamp = db.Column(db.DateTime, default=datetime.datetime.now)
    modified_timestamp = db.Column(db.DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)
    related_id = db.Column(db.Integer, db.ForeignKey('some_other_sql_table_name.id'))
    related = db.relationship(SomeOtherFlaskSQLAlchemyModel, backref=db.backref('related_backref', lazy='dynamic'))

      

Once you uncheck the django models and Refc-sqlalchemy models, you can use the django awesome migrate command to create tables with the correct schema. The flask-sqlalchemy models will then notice that they have been created and auto-populated. So you only have to worry about the django model (minus the timestamp fields and model relationships), and just let flask-sqlalchemy reflect the rest for you.

The last thing you need to do is configure Flask-SQLAlchemy and Django to the same SQL database. I assume you know how to do this. One hint I'll give you is that settings.py for Flask and Django can be the same file without any conflicts.

+4


source


First, don't do it; you are in a world of pain. Use API to transfer data between applications.



But if you are ok with it, there are no problems with migrations. Write everything in one application only Django or Alembic and run them there. Since they are using a database table, whatever is in it.

+2


source