buggyrace / buggy-race-server

Race server and supporting material for running a "Buggy Racing" Python programming project
https://www.buggyrace.net
Other
1 stars 0 forks source link

fix broken heroku deploy before db is populated #196

Closed davewhiteland closed 5 months ago

davewhiteland commented 5 months ago

The RHUL/CIM deploy broke heroku deploy, but this looks like it might be because the in-Python fix isn't quite robust enough: the intent of BYPASSING_DB_CONFIG_KEY is good but it deffo doesn't look like it's working on a new (Heroku) deploy!

Basically shouldn't be attempting set_and_save_config_setting if there's no database ready yet, which is the case when app is being instantiated for migrations (hence checking for flask being run with db as an argument (as in flask db upgrade).

From Heroku (failed!) build log:

  File "/tmp/build_25dda996/buggy_race_server/app.py", line 84, in create_app
    save_config_env_overrides_to_db(app)
  File "/tmp/build_25dda996/buggy_race_server/utils.py", line 100, in save_config_env_overrides_to_db
    set_and_save_config_setting(app, name, value)
  File "/tmp/build_25dda996/buggy_race_server/utils.py", line 154, in set_and_save_config_setting
    setting = db.session.query(Setting).filter_by(id=name).first()

...

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "settings" does not exist
LINE 2: FROM settings 
             ^
[SQL: SELECT settings.id AS settings_id, settings.value AS settings_value 
FROM settings 
WHERE settings.id = %(id_1)s 
 LIMIT %(param_1)s]
[parameters: {'id_1': 'AUTHORISATION_CODE', 'param_1': 1}]
davewhiteland commented 5 months ago

Testing locally on command line, with an empty database:

...so that isn't the same behaviour as on Heroku, unless somehow BYPASSING_DB_CONFIG_KEY is set to something like 0 implicitly?

davewhiteland commented 5 months ago

Adding this to utils — this is a better test than trying to catch exceptions, because exceptions were specific to the kind of database used (in practice, up on Heroku it's always Postgres, but trying to keep this general for local dev work)

def has_settings_table():
    engine = db.create_engine(current_app.config.get("DATABASE_URL"))
    insp = db.inspect(engine)
    return insp.has_table(Setting.__table__.name)
davewhiteland commented 5 months ago

oof almost there...

Can't load plugin: sqlalchemy.dialects:postgres

SqlAlchemy uses a different name for Postgres than Heroku does in its DATABASE_URL... but we've already fixed this in the ConfigFromEnv class with SQLALCHEMY_DATABASE_URI

  File "/tmp/build_f7940caa/buggy_race_server/utils.py", line 90, in has_settings_table
    engine = db.create_engine(current_app.config.get("DATABASE_URL"))
  File "<string>", line 2, in create_engine
  File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 281, in warned
    return fn(*args, **kwargs)  # type: ignore[no-any-return]
  File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/engine/create.py", line 552, in create_engine
    entrypoint = u._get_entrypoint()
  File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/engine/url.py", line 754, in _get_entrypoint
    cls = registry.load(name)
  File "/app/.heroku/python/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 368, in load
    raise exc.NoSuchModuleError(
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
davewhiteland commented 5 months ago

fixed in 5049c019eafb2bfa3619c44005e05ef033e56721