Как настроить Flask-Migrate с правильной ссылкой на базу данных?

Я создаю приложение для фляг и пытаюсь настроить миграцию базы данных с помощью Flask-Migrate. У меня это работает, но у меня странная проблема: приложение/миграция не ищет файл .db в одном и том же месте, и мне нужно знать, как заставить их искать в одном и том же месте.

Мое приложение работает отлично, и я не получаю никаких ошибок. Flask-Migrate работает отлично, и я не получаю ошибок. Это упрощенный макет моего приложения в настоящее время:

app.py
app/
|- __init__.py
|- config.py

Когда я запускаю «flask run», он думает, что база данных находится здесь:

app.py
app/
|- __init__.py
|- config.py
|- app.db  <--(In the app folder)

Но когда я запускаю «flask db upgrade», он думает, что база данных находится здесь:

app.py
app.db  <--(In the main folder)
app/
|- __init__.py
|- config.py

У меня для SQLALCHEMY_DATABASE_URI установлено значение «sqlite:///app.db», и я действительно могу заставить их работать правильно, если постоянно меняю SQLALCHEMY_DATABASE_URI между «sqlite:///app.db» и «sqlite:///». ../app.db' между выполнением двух команд.

файл app.py

from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run(debug=True)

упрощенный __init__.py file:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from app.config import Config
from flask_migrate import Migrate

db = SQLAlchemy()
migrate = Migrate()

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(Config)

    db.init_app(app)
    migrate.init_app(app, db)

    from app.routes import main
    app.register_blueprint(main)

    return app

упрощенный файл config.py

import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = os.environ.get('SQLALCHEMY_DATABASE_URI')

Я ожидаю, что flask run и flask db upgrade увидят файл .db в одном и том же месте, но это не так. Вместо этого они видят их в дочерней или родительской папке соответственно.


person chfaber    schedule 05.08.2019    source источник


Ответы (2)


Проблема в том, что вы используете URL-адрес своей базы данных SQLite, поэтому каждый раз, когда приложение меняет текущий рабочий каталог, местоположение вашей базы данных будет вычисляться снова относительно нового текущего каталога.

Решение простое, используйте абсолютный URL. Это делается, когда вы устанавливаете переменную среды SQLALCHEMY_DATABASE_URI, значение должно быть примерно таким:

export SQLALCHEMY_DATABASE_URI="sqlite:////home/yourname/yourapp/app.db"

Обратите внимание, что это sqlite:, за которым следуют четыре слэша, а не три. Первые две косые черты являются разделителем между схемой URL-адреса и остальной частью URL-адреса. Третья косая черта отделяет хост/порт от пути (хост и порт пусты в URL-адресах SQLite). Четвертая косая черта — это начало абсолютного пути к файлу вашей базы данных.

person Miguel    schedule 05.08.2019
comment
Благодарю вас! Это сработало отлично. Я видел, что можно использовать абсолютный URL-адрес, но я настроил его в своей голове на использование относительного URL-адреса. Однако абсолют решил проблему, и теперь Flask-Migrate работает как часы. - person chfaber; 05.08.2019

Мне не нравятся абсолютные URI.

в env.py:

config.set_main_option('sqlalchemy.url', current_app.config.get('SQLALCHEMY_DATABASE_URI').replace('%', '%%'))

(вам нужно будет прокомментировать эти строки, чтобы заставить его работать)

в основном использует то, что вы используете в SQLALCHEMY_DATABASE_URI.

в моем случае sqlite:///db.sqlite, что может вызвать проблемы, описанные выше, по причинам, изложенным выше (проблемы с относительным путем)

Чтобы избежать описанной вами проблемы, используйте другой (относительный) uri для env.py.

(то есть в файле alembic.ini, в разделе [alembic]):

[перегонный куб]

sqlalchemy.url = sqlite:///app/db.sqlite

Итак, теперь у вас будет правильный относительный путь для всех различных потребностей. Это сработало для меня, именно в этом случае.

person iair    schedule 21.01.2020