Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically generate migrations #10

Closed
l1f opened this issue Mar 14, 2023 · 12 comments
Closed

Automatically generate migrations #10

l1f opened this issue Mar 14, 2023 · 12 comments
Labels
question Further information is requested

Comments

@l1f
Copy link

l1f commented Mar 14, 2023

I am currently trying to get the auto-generate to work. I have orientated myself on your examples in the retrofun repo.

However, the migration files are always empty and look like this:

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '27b94fadbd77'
down_revision = None
branch_labels = None
depends_on = None


def upgrade(engine_name: str) -> None:
    globals()["upgrade_%s" % engine_name]()


def downgrade(engine_name: str) -> None:
    globals()["downgrade_%s" % engine_name]()


def upgrade_() -> None:
    pass


def downgrade_() -> None:
    pass

I proceeded as described in the documentation and first initialized with python -m alchemical.alembic.cli init migrations alembic and then tried to create a migration with alembic revision --autogenerate -m "Initial migration".

I have also adjusted the alchemical_db variable accordingly.

Am I missing something?

@miguelgrinberg
Copy link
Owner

An empty migration means that the models and the database have the same contents, so my guess is that you have already configured your database and now alembic finds nothing needs to be migrated.

@miguelgrinberg miguelgrinberg added the question Further information is requested label Mar 14, 2023
@l1f
Copy link
Author

l1f commented Mar 14, 2023

the database is empty :/

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Mar 14, 2023

If that is true, then for alembic to make an empty migration your database metadata must be empty as well. Make sure you import your models so that they are seen by SQLAlchemy and Alembic.

@l1f
Copy link
Author

l1f commented Mar 14, 2023

I'm not quite sure what you mean.

What I have done so far is in the extensions.py I created Alchemical as variable db and then initialized it in the app.py via the init_app method.

from alchemical.flask import Alchemical

db = Alchemical()
from flask import Flask
from webapp.extensions import queue, db

def launch():
    """Create a Flask app."""

    app = Flask(__name__)

    app.config["AMQP_QUEUE"] = "amqp://rabbitmq"
    app.config["ALCHEMICAL_DATABASE_URI"] = "mysql://root:root@mysql/tech"

    configure_blueprints(app)
    configure_extensions(app)

    return app
    
 # snip
 
 def configure_extensions(app: Flask):
    queue.init_app(app)
    db.init_app(app)

Then I created a class Language in models.py, which inherits from db.Model.

from webapp.extensions import db
import sqlalchemy.orm as so
import sqlalchemy as sa


class Language(db.Model):
    __tablename__ = "languages"

    id: so.Mapped[int] = so.mapped_column(primary_key=True)
    name: so.Mapped[str] = so.mapped_column(sa.String(32), index=True, unique=True)

This last step, is what you mean by "Make sure you import your models so that they are seen by SQLAlchemy and Alembic"?

@miguelgrinberg
Copy link
Owner

Your models are in models.py. If no other modules import models.py, then your models will not be known. I hope this is clear, the models that you have in models.py have to be imported somewhere, because if nobody imports them, then it is as if they don't exist.

Try adding an import models in your env.py file.

@l1f
Copy link
Author

l1f commented Mar 15, 2023

ahh... I see. But there is a place where this is imported. in api/__init__.py
(and api is imported into the app.py file to be used as a blueprint.)

from quart import Blueprint
from webapp.models import Language
import sqlalchemy as sa
from webapp.extensions import db

api = Blueprint("api", __name__, url_prefix="/api")


@api.route("/test")
async def api_test():
    query = sa.select(Language)

    result = await db.session.execute(query)
    result = result.scalar_one()

    return result.name

I also tried to import the models.py in the env.py file, but that did not change anything.

@miguelgrinberg
Copy link
Owner

I am out of ideas then. Try Alembic on its own (without the Alchemical's init command) to determine if the problem is in Alembic or Alchemical. Then submit a small example project to Alembic or myself depending on the results.

@l1f
Copy link
Author

l1f commented Mar 15, 2023

Thanks for the help!

I'll get back to you as soon as I've found something out.

@l1f
Copy link
Author

l1f commented Mar 15, 2023

Could it be a problem that the flask is initialized via the launch function and the config value for ALCHEMICAL_DATABASE_URI is set at that time?

As far as I understand correctly, the db variable from the extensions.py is imported by alembic. But the factory function is not called and therefore not the config parameter. Right?

So alembic can not look into the database at all or?

@miguelgrinberg
Copy link
Owner

I guess it could be, but if Alembic does not know what the database is I would expect it would error, not just tell you there's nothing to migrate.

It's easy enough to confirm, right? Just call your factory function in env.py, for example, and that should fix the problem is this is the issue.

@l1f
Copy link
Author

l1f commented Mar 15, 2023

I would also have thought that there would be an error. But calling the factory function actually solves it.

I would see if I can find a nicer solution for this. If I find something, would that be something for the alchemical docs?

@miguelgrinberg
Copy link
Owner

Yes, this sounds like something I would want to document.

I normally use Flask-Migrate when working with migrations in a Flask + Alchemical app, and this is why I have missed this potential problem in my projects.

Thanks for your patience in working through this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants