簡體   English   中英

如何管理共享一個數據庫模型的django和flask應用程序?

[英]How to manage django and flask application sharing one database model?

我有兩個用燒瓶和django寫的存儲庫。
這些項目共享數據庫模型,該模型用燒寫的SQLAlchemy編寫,並用Django ORM編寫。
當我在flask中編寫遷移腳本作為alembic時,django項目如何與該腳本一起遷移?

我也想到了SQLAlchemy的Django。 但我無法找到使用SQLAlchemy的Django項目。 這是個壞主意嗎?
謝謝。

在我們的工作場所,我們在同一個網站上使用django和flask。 原因是django的管理員和模型系統編寫代碼非常快,它可以作為我們的后端(僅限員工)管理界面。 另一方面,在燒瓶中編寫前端要容易得多,因為每個頁面都可以像一個python函數和Jinja2模板一樣簡單。 Flask表單需要一個額外的表單模型類(它易於編寫),它指定表單中的所有字段,如果要將表單響應保存到SQL數據庫,則需要第二個SQLAlchemy模型。 如果你要在django中編寫相同的表單,最簡單的情況是你不編寫表單模型,因為django框架隱式地從sql模型生成它。 但是,在燒瓶中寫“常規”頁面仍然更快。

至於讓兩者一起玩得很好,它最終如何工作是我們首先編寫django模型,因為數據庫管理和sql架構遷移被烘焙到django中。 然后我們使用SQLAlchemy的一個名為“reflection”的功能,它讀取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'

Flask-SQLAlchemy模型:

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數據庫。 在嘗試甚至導入模型所在的.py文件之前,需要正確配置Flask-SQLAlchemy及其db對象,否則在導入時您將獲得一些令人討厭的錯誤。 如果將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

當然, app需要加載Flask-SQLAlchemy配置的設置,否則無效。 通常from application import db獲取模型文件更好,並且在設置db之后from my_models import *執行from my_models import *

正確配置后,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模型和反射的flask-sqlalchemy模型,那么你可以使用django的awesome migrate命令來創建具有正確模式的表。 然后,flask-sqlalchemy模型將注意到它們已經被創建並自動填充。 這樣,您只需要擔心django模型(減去時間戳字段和模型關系),然后讓flask-sqlalchemy為您反映其余部分。

您需要做的最后一件事是將Flask-SQLAlchemy和Django配置為指向同一個SQL數據庫。 我猜你知道怎么做。 我給你的一個提示是Flask和Django的settings.py可以是同一個文件而沒有任何沖突。

首先,不要這樣做; 你是一個痛苦的世界。 使用API​​在應用之間傳遞數據。

但是,如果您辭職,那么遷移實際上沒有任何問題。 只在一個應用程序中寫入所有這些,Django或Alembic並在那里運行它們。 由於他們共享一個數據庫表,所以就是這樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM