config.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. """
  2. Database configuration utils
  3. """
  4. from sqlalchemy.orm import declarative_base
  5. from sqlalchemy import MetaData
  6. import sqlalchemy as sa
  7. from flask_sqlalchemy import SQLAlchemy
  8. from flask import Flask
  9. from flexmeasures.data.models import naming_convention
  10. db: sa = (
  11. None # typed attributes unavailable in flask-sqlalchemy, see https://github.com/pallets/flask-sqlalchemy/issues/867
  12. )
  13. Base = None # type: ignore
  14. session_options = None
  15. def init_db():
  16. """Initialise the database object"""
  17. global db, Base, session_options
  18. db = SQLAlchemy(
  19. session_options=session_options,
  20. metadata=MetaData(naming_convention=naming_convention),
  21. )
  22. Base = declarative_base(metadata=db.metadata)
  23. Base.query = None
  24. def configure_db_for(app: Flask):
  25. """Call this to configure the database and the tools we use on it for the Flask app.
  26. This should only be called once in the app's lifetime."""
  27. global db, Base
  28. with app.app_context():
  29. db.init_app(app)
  30. app.db = db
  31. Base.query = db.session.query_property()
  32. # Import all modules here that might define models so that
  33. # they will be registered properly on the metadata. Otherwise,
  34. # you will have to import them first before calling configure_db().
  35. from flexmeasures.data.models import ( # noqa: F401
  36. time_series,
  37. data_sources,
  38. user,
  39. task_runs,
  40. forecasting,
  41. ) # noqa: F401
  42. # This would create db structure based on models, but you should use `flask db upgrade` for that.
  43. # Base.metadata.create_all(bind=db.engine)
  44. def commit_and_start_new_session(app: Flask):
  45. """Use this when a script wants to save a state before continuing
  46. Not tested well, just a starting point - not recommended anyway for any logic used by views or tasks.
  47. Maybe session.flush() can help you there."""
  48. global db, Base, session_options
  49. db.session.commit()
  50. db.session.close()
  51. db.session.remove()
  52. db.session = db.create_scoped_session(options=session_options)
  53. Base.query = db.session.query_property()
  54. from flask_security import SQLAlchemySessionUserDatastore
  55. from flexmeasures.data.models.user import User, Role
  56. app.security.datastore = SQLAlchemySessionUserDatastore(db.session, User, Role)
  57. init_db() # This makes sure this module can be imported from right away