[英]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.