Python 如何管理django和flask应用程序共享一个数据库模型?

Python 如何管理django和flask应用程序共享一个数据库模型?,python,django,flask,sqlalchemy,Python,Django,Flask,Sqlalchemy,我有两个用flask和django编写的存储库。 这些项目共享用flask中的SQLAlchemy和Django ORM编写的数据库模型。 当我以alembic的身份在flask中编写迁移脚本时,django项目如何使用该脚本进行迁移 我还想到了Django和SQLAlchemy。但我找不到使用SQLAlchemy的Django项目。那是个坏主意吗? 谢谢。首先,不要这样做;你会陷入痛苦的世界。使用API在应用程序之间传递数据 但是,如果您愿意这样做,那么迁移实际上没有任何问题。只在一个应用程序

我有两个用flask和django编写的存储库。
这些项目共享用flask中的SQLAlchemy和Django ORM编写的数据库模型。
当我以alembic的身份在flask中编写迁移脚本时,django项目如何使用该脚本进行迁移

我还想到了Django和SQLAlchemy。但我找不到使用SQLAlchemy的Django项目。那是个坏主意吗?

谢谢。

首先,不要这样做;你会陷入痛苦的世界。使用API在应用程序之间传递数据


但是,如果您愿意这样做,那么迁移实际上没有任何问题。只在一个应用程序(Django或Alembic)中编写并运行它们。因为他们共享一个数据库表,所以就只有这些了。

在我们的工作场所,我们在同一个网站上同时使用django和flask。这是因为django的管理和模型系统编写代码非常快,并且它充当我们的后端(仅限员工)管理界面。另一方面,在flask中编写前端要容易得多,因为每个页面都可以像一个python函数和一个Jinja2模板一样简单。Flask表单需要一个额外的表单模型类(很容易编写),该类指定表单中的所有字段,如果表单响应要保存到SQL数据库,则需要第二个SQLAlchemy模型。如果要在django中编写相同的表单,最简单的情况是不编写表单模型,因为django框架隐式地从sql模型生成表单模型。不过,在烧瓶中写“常规”页面要快得多

至于如何让这两种方法很好地结合起来,最终的结果是我们首先编写django模型,因为数据库管理和sql模式迁移都是在django中进行的。然后,我们使用SQLAlchemy的一个称为“反射”的功能读取sql数据库并从模式生成sql模型。这样,当我们对django模型进行更改时,我们运行manage.py migrate(它将模式更改部署到sql数据库),并且SQLAlchemy模型自动反映新模式,而无需接触Flask SQLAlchemy模型。下面是一个示例,其中包括一些外键内容和一些时间戳,当您使用ORM保存模型时,这些时间戳会自动更新。我之所以包括这些,是因为它们都是常见的用例,都需要额外的代码

Django模型:

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'
炼金术模型:

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's 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'))
以这种方式定义Flask SQLAlchemy模型需要注意的是,它们依赖于SQL数据库。Flask SQLAlchemy及其
db
对象需要正确配置,然后才能尝试导入该模型所在的.py文件,否则导入时会出现一些严重错误。如果将
db
的定义与模型放在同一个文件中,并将其初始化如下:

from flask import current_app
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
db.init_app(current_app)
with app.app_context():
    import module_with_flask_sqlalchemy_model
然后您需要像这样进行导入:

from flask import current_app
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
db.init_app(current_app)
with app.app_context():
    import module_with_flask_sqlalchemy_model
当然,
app
需要为Flask SQLAlchemy加载配置设置,否则将无法工作。通常最好只从应用程序导入数据库中导入模型文件do
,并在设置
db
后从my_models导入*
中导入application.py do

正确配置后,Flask SQLAlchemy模型将等效于定义如下的Flask SQLAlchemy模型:

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'))
一旦放下django模型和sqlalchemy模型,就可以使用django的awesomegrate命令创建具有正确模式的表。然后炼金术模型会注意到它们已经被创建并自动填充自己。这样,您只需担心django模型(减去时间戳字段和模型关系),然后让Alchemy为您反映其余部分


您需要做的最后一件事是配置Flask SQLAlchemy和Django以指向同一个SQL数据库。不过我想你知道怎么做。我给你的一个提示是,Flask和Django的settings.py可以是同一个文件,没有任何冲突。

我明白了。编写一次回购协议是个好主意。我认为用SQLAlchemy迁移django也是解决方案之一,但我找不到django和SQLAlchemy项目。也许考虑像Redis这样的东西在两个应用程序之间进行通信是值得的。