python - Flask-Migrate/Alembic 未使用基类和多文件结构检测模型
问题描述
这个问题已经被问了一百万次,但似乎没有一个解决方案对我有用。我应该注意到我在其他项目中经常处理切线问题
目前我正在使用 flask-sqlalchemy、flask-migrate 和 postgresql。
文件结构:
├── app
│ ├── __init__.py
│ ├── main
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── users.py
│ ├── models
│ │ ├── annotations.py
│ │ ├── __init__.py
│ │ ├── mixins.py
│ │ └── users.py
├── config.py
├── docker-compose.yml
├── Dockerfile
├── icc2.py <-- the app.py
├── migrations
app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from elasticsearch import Elasticsearch
from flask_migrate import Migrate
from config import Config
db = SQLAlchemy()
migrate = Migrate()
def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)
db.init_app(app)
migrate.init_app(app, db)
app.es = Elasticsearch([app.config['ELASTICSEARCH_URL']]) \
if app.config['ELASTICSEARCH_URL'] else None
from app.main import bp as main_bp
app.register_blueprint(main_bp, url_prefix='/_api')
CORS(app, resources={r"/_api/*": {"origins": "*"}})
return app
icc2.py
from app import create_app, db
from app.models import classes
app = create_app()
@app.shell_context_processor
def make_shell_context():
print(db)
return dict(db=db, **classes)
app/models/mixins.py
from app import db
from sqlalchemy.ext.declarative import declared_attr, as_declarative
@as_declarative()
class Base(db.Model):
"""This Base class does nothing. It is here in case I need to expand
implement something later. I feel like it's a good early practice.
Attributes
----------
id : int
The basic primary key id number of any class.
Notes
-----
The __tablename__ is automatically set to the class name lower-cased.
There's no need to mess around with underscores, that just confuses the
issue and makes programmatically referencing the table more difficult.
"""
__abstract__ = True
id = db.Column(db.Integer, primary_key=True)
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
app/models/users.py
(annotations.py
类似)
import time
from datetime import datetime
from app import db
from app.models.mixins import Base
class User(Base):
auth0id = db.Column(db.String(64), index=True)
last_seen = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self):
return f"<User {self.displayname}>"
def __str__(self):
return self.displayname
app/models/__init__.py
import pkgutil
import os
import importlib
from .mixins import Base
pkg_dir = os.path.dirname(__file__)
for (module_loader, name, ispkg) in pkgutil.iter_modules([pkg_dir]):
importlib.import_module('.' + name, __package__)
classes = {cls.__name__: cls for cls in Base.__subclasses__()}
迭代来自一个 stackoverflow 片段,这样我就可以让一个类中的模型暴露给烧瓶外壳命名空间。
我可能不需要将这两个类放在两个单独的文件中,但我的上一个项目最终有 30 个左右的模型,因此组织需要进行一些拆分,所以这只是我开发的一种实践。
据我了解,alembic 需要先查看对象的元数据,然后才能生成模型,但是在app/__init__.py
实例化 migrate 时,数据库还没有引擎。事实上,只是为了测试引擎是如何创建的,我添加了 3 个打印语句来icc2.py
打印 db 并查看它是否有引擎,如下所示:
from app import create_app, db
from app.models import classes
app = create_app()
print(db)
@app.shell_context_processor
def make_shell_context():
print(db)
return dict(db=db, **classes)
print(db)
唯一没有显示的打印调用<SQLAlchemy engine=None>
在make_shell_context()
函数内。
最后,flask migrate “初始迁移”的输出:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.env] No changes in schema detected.
那么如何将我的元数据公开给烧瓶迁移呢?
解决方案
推荐阅读
- vb.net - 在 Visual Basic 中旋转 BMP
- c++ - 从 C++ 项目调用 docker 容器
- wordpress - 如何在 WordPress 中禁用古腾堡
- ubuntu - AWK 提取列中具有相同单词的前两行
- azure - 通过 Azure 应用程序代理调用本地 OAuth API
- sql - 如何通过在oracle sql中同时比较多条记录来获取行
- python - 将 pandas 数据框转换为具有唯一整数对的元组列表作为第一个条目
- apache-flink - 如何使用 Flink CEP 实现模式以匹配暴力登录和端口扫描攻击
- vue.js - Vue - 检测插槽内的组件
- azure - 使用 azure datafactory 活动将 dta 从 azure blob 容器发送到 azure 函数