#481 Rationalize the instantiation of the DB session
Merged 6 years ago by abompard. Opened 6 years ago by abompard.
abompard/fedora-hubs fix/reorg-session  into  develop

file modified
+3 -3
@@ -20,15 +20,15 @@ 

  import hubs.app

  import hubs.widgets

  import hubs.models

+ from hubs.database import Session

  

- 

+ db = Session()

  empty, full = 0, 0

- session = hubs.app.session

  

  # Register widgets

  hubs.widgets.registry.register_list(hubs.app.app.config["WIDGETS"])

  

- for w_instance in session.query(hubs.models.Widget).all():

+ for w_instance in db.query(hubs.models.Widget).all():

      if not w_instance.enabled:

          continue

      for fn_name, fn_class in w_instance.module.get_cached_functions().items():

file modified
+5 -8
@@ -7,12 +7,9 @@ 

  from __future__ import unicode_literals, print_function

  

  import hubs.models

- from hubs.utils import get_fedmsg_config

- 

- fedmsg_config = get_fedmsg_config()

- 

- session = hubs.models.init(fedmsg_config['hubs.sqlalchemy.uri'])

+ from hubs.database import Session

  

+ db = Session()

  username = input('What user do you want to delete: ')

  openid = '%s.id.fedoraproject.org' % username

  print("Looking for account %r" % openid)
@@ -21,13 +18,13 @@ 

      print("No such user %r" % openid)

  else:

      print("Found %r.  Deleting." % user)

-     session.delete(user)

+     db.delete(user)

  

  hub = hubs.models.Hub.get(username)

  if not hub:

      print("No such hub %r" % username)

  else:

      print("Found %r.  Deleting." % hub)

-     session.delete(hub)

+     db.delete(hub)

  

- session.commit()

+ db.commit()

file modified
+19 -3
@@ -32,12 +32,28 @@ 

      app.config.from_envvar('HUBS_CONFIG')

  

  fedmsg_config = get_fedmsg_config()

- session = hubs.models.init(fedmsg_config['hubs.sqlalchemy.uri'])

+ 

+ 

+ # Database

+ 

+ from hubs.database import Session  # noqa: E402

  

  

  @app.before_request

  def store_db():

-     flask.g.db = session

+     flask.g.db = Session()

+ 

+ 

+ @app.teardown_appcontext

+ def shutdown_session(response_or_exc):

+     # Auto-commit on each successful request

+     if app.config.get('SQLALCHEMY_COMMIT_ON_TEARDOWN', True):

+         if response_or_exc is None and hasattr(flask.g, "db"):

+             flask.g.db.commit()

+     if not app.testing:

+         # Don't remove the session when testing, we'll need it for assertions.

+         Session.remove()

+     return response_or_exc

  

  

  class CustomJSONEncoder(flask.json.JSONEncoder):
@@ -97,7 +113,7 @@ 

              flask.session.modified = True

          flask.g.auth = munch.Munch(**flask.session["auth"])

          user = hubs.models.User.get_or_create(

-             flask.g.db, username=flask.session["auth"]["nickname"],

+             username=flask.session["auth"]["nickname"],

              fullname=flask.session["auth"]["fullname"])

          flask.g.user = user

      else:

file modified
+3 -2
@@ -31,6 +31,7 @@ 

  import retask.queue

  

  import hubs.app

+ import hubs.database

  import hubs.feed

  import hubs.models

  import hubs.widgets.base
@@ -38,7 +39,6 @@ 

  

  log = logging.getLogger('hubs.backend.triage')

  fedmsg_config = hubs.app.fedmsg_config

- session = hubs.app.session

  

  

  def triage(msg):
@@ -90,7 +90,8 @@ 

  def get_widgets():

      # Get a list of all our widgets:

      log.debug("Querying for all widgets.")

-     widgets = session.query(hubs.models.Widget).all()

+     db = hubs.database.Session()

+     widgets = db.query(hubs.models.Widget).all()

      # Filter out widgets that have been disabled.

      widgets = [w for w in widgets if w.enabled]

      # Randomize so that all the triage daemons work on widgets in different

file modified
+8 -7
@@ -36,6 +36,7 @@ 

  import retask.queue

  

  import hubs.app

+ import hubs.database

  import hubs.feed

  import hubs.models

  import hubs.widgets.base
@@ -43,7 +44,6 @@ 

  

  log = logging.getLogger('hubs.backend.worker')

  fedmsg_config = hubs.app.fedmsg_config

- session = hubs.app.session

  

  

  def widget_cache_work(widget_idx, fn_name):
@@ -55,16 +55,14 @@ 

      fn_class(widget).rebuild()

  

  

- def handle_widget_cache(widget_idx, fn_name):

+ def handle_widget_cache(db, widget_idx, fn_name):

      try:

          with hubs.app.app.app_context():  # so url_for works

              widget_cache_work(widget_idx, fn_name)

-         session.commit()  # transaction is committed here

+         db.commit()  # transaction is committed here

      except Exception:

-         session.rollback()  # rolls back the transaction

+         db.rollback()  # rolls back the transaction

          raise

-     finally:

-         session.close()

  

  

  def parse_args(args):
@@ -84,6 +82,9 @@ 

      # XXX - for flask.url_for to work

      hubs.app.app.config['SERVER_NAME'] = '0.0.0.0:5000'

  

+     # Connect to the DB

+     db = hubs.database.Session()

+     # Connect to the Redis queues

      name = fedmsg_config['hubs.redis.work-queue-name']

      log.info("Worker starting, connecting to retask queue %r." % name)

      queue = retask.queue.Queue(name)
@@ -102,7 +103,7 @@ 

              sse_task = None

              item_type = item.get("type", "widget-cache")

              if item_type == "widget-cache":

-                 handle_widget_cache(item['idx'], item['fn_name'])

+                 handle_widget_cache(db, item['idx'], item['fn_name'])

                  sse_task = {

                      "event": "hubs:widget-updated",

                      "data": item["idx"],

file added
+78
@@ -0,0 +1,78 @@ 

+ # -*- coding: utf-8 -*-

+ #

+ # Copyright © 2017  Red Hat, Inc.

+ #

+ # This copyrighted material is made available to anyone wishing to use,

+ # modify, copy, or redistribute it subject to the terms and conditions

+ # of the GNU Lesser General Public License (LGPL) version 2, or

+ # (at your option) any later version.  This program is distributed in the

+ # hope that it will be useful, but WITHOUT ANY WARRANTY expressed or

+ # implied, including the implied warranties of MERCHANTABILITY or FITNESS

+ # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for

+ # more details.  You should have received a copy of the GNU Lesser General

+ # Public License along with this program; if not, write to the Free

+ # Software Foundation, Inc.,

+ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

+ #

+ # Any Red Hat trademarks that are incorporated in the source

+ # code or documentation are not subject to the GNU General Public

+ # License and may only be used or replicated with the express permission

+ # of Red Hat, Inc.

+ #

+ 

+ from __future__ import unicode_literals

+ 

+ import logging

+ 

+ from alembic.config import Config as AlembicConfig

+ from alembic import command as alembic_command

+ from sqlalchemy import create_engine

+ from sqlalchemy.ext.declarative import declarative_base

+ from sqlalchemy.orm import sessionmaker

+ from sqlalchemy.orm import scoped_session

+ 

+ from hubs.utils import get_fedmsg_config

+ 

+ 

+ log = logging.getLogger(__name__)

+ 

+ 

+ BASE = declarative_base()

+ 

+ # http://docs.sqlalchemy.org/en/latest/orm/contextual.html#unitofwork-contextual

+ Session = scoped_session(sessionmaker())

+ BASE.query = Session.query_property()

+ 

+ 

+ def init(db_url, debug=False, create=False):

+     """ Create the tables in the database using the information from the

+     url obtained.

+ 

+     Arguments:

+         db_url (str): URL used to connect to the database. The URL contains

+             information with regards to the database engine, the host to

+             connect to, the user and password and the database name. For

+             example: ``<engine>://<user>:<password>@<host>/<dbname>``.

+         debug (bool): a boolean specifying whether we should have the verbose

+             output of sqlalchemy or not.

+         create (bool): a boolean specifying whether we should create the

+             database or not.

+     """

+     engine = create_engine(db_url, echo=debug)

+     if engine.name == "sqlite":

+         engine.execute("PRAGMA foreign_keys=ON")

+ 

+     if create:

+         BASE.metadata.create_all(engine)

+         # Stamp the database with the lastest Alembic revision:

+         # http://alembic.zzzcomputing.com/en/latest/cookbook.html#building-an-up-to-date-database-from-scratch

+         alembic_cfg = AlembicConfig()

+         alembic_cfg.set_main_option("script_location", "hubs:migrations")

+         alembic_command.stamp(alembic_cfg, "head")

+     # http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#adding-additional-configuration-to-an-existing-sessionmaker

+     Session.configure(bind=engine)

+ 

+ 

+ # Now setup the default scoped session maker.

+ fedmsg_config = get_fedmsg_config()

+ init(fedmsg_config['hubs.sqlalchemy.uri'])

file modified
+2 -2
@@ -5,7 +5,7 @@ 

  import hubs.models

  

  

- def add_user_widgets(session, hub, username, fullname):

+ def add_user_widgets(hub, username, fullname):

      """ Some defaults for an individual user's hub. """

      # The feed widget works, but it needs to be cleaned up lots before we

      # throw it in by default.
@@ -79,7 +79,7 @@ 

      return hub

  

  

- def add_group_widgets(session, hub, name, summary,

+ def add_group_widgets(hub, name, summary,

                        # These are all things that come from FAS

                        apply_rules=None,

                        irc_channel=None,

file modified
+4 -4
@@ -7,7 +7,7 @@ 

  

  

  try:

-     import hubs

+     import hubs  # noqa: F401

  except ImportError:

      import os

      import sys
@@ -15,8 +15,8 @@ 

          raise

      sys.path.append(os.getcwd())

  

- import hubs.app

- from hubs.models import BASE

+ from hubs.database import BASE

+ from hubs.utils import get_fedmsg_config

  

  

  # This is the Alembic Config object, which provides
@@ -27,7 +27,7 @@ 

      # This line sets up loggers basically.

      fileConfig(context.config.config_file_name)

  

- fedmsg_config = hubs.app.fedmsg_config

+ fedmsg_config = get_fedmsg_config()

  url = fedmsg_config['hubs.sqlalchemy.uri']

  target_metadata = BASE.metadata

  

file modified
+31 -97
@@ -33,40 +33,16 @@ 

  import bleach

  import sqlalchemy as sa

  

- from alembic import command as alembic_command

- from alembic.config import Config as AlembicConfig

- from sqlalchemy import create_engine

- from sqlalchemy.ext.declarative import declarative_base

- from sqlalchemy.orm import sessionmaker

- from sqlalchemy.orm import scoped_session

  from sqlalchemy.orm import relation

  from sqlalchemy.orm import backref

  from sqlalchemy.orm.session import object_session

  

- import fedmsg

- import fedmsg.utils

- 

  import hubs.defaults

  import hubs.widgets

  from hubs.authz import ObjectAuthzMixin, AccessLevel

+ from hubs.database import BASE, Session

  from hubs.utils import username2avatar

  

- 

- class HubsBase(object):

-     def notify(self, username, changed):

-         obj = type(self).__name__.lower()

-         topic = obj + ".update"

-         fedmsg.publish(

-             topic=topic,

-             msg=dict(

-                 username=username,

-                 changed=changed,

-             )

-         )

- 

- 

- BASE = declarative_base(cls=HubsBase)

- 

  log = logging.getLogger(__name__)

  

  
@@ -77,35 +53,6 @@ 

      return location + choice

  

  

- def init(db_url, debug=False, create=False):

-     """ Create the tables in the database using the information from the

-     url obtained.

- 

-     :arg db_url, URL used to connect to the database. The URL contains

-         information with regards to the database engine, the host to

-         connect to, the user and password and the database name.

-           ie: <engine>://<user>:<password>@<host>/<dbname>

-     :kwarg debug, a boolean specifying whether we should have the verbose

-         output of sqlalchemy or not.

-     :return a session that can be used to query the database.

- 

-     """

-     engine = create_engine(db_url, echo=debug)

-     if engine.name == "sqlite":

-         engine.execute("PRAGMA foreign_keys=ON")

- 

-     if create:

-         BASE.metadata.create_all(engine)

-         # Stamp the database with the lastest Alembic revision:

-         # http://alembic.zzzcomputing.com/en/latest/cookbook.html#building-an-up-to-date-database-from-scratch

-         alembic_cfg = AlembicConfig()

-         alembic_cfg.set_main_option("script_location", "hubs:migrations")

-         alembic_command.stamp(alembic_cfg, "head")

-     session = scoped_session(sessionmaker(bind=engine))

-     BASE.query = session.query_property()

-     return session

- 

- 

  ROLES = ['subscriber', 'member', 'owner', 'stargazer']

  

  
@@ -172,15 +119,6 @@ 

              if idle > limit:

                  return name

  

-     @classmethod

-     def get_or_create(cls, session, name, summary, **extra):

-         self = cls.by_name(name)

-         if not self:

-             self = cls.create_group_hub(session, name, summary, **extra)

-             session.add(self)

-             session.commit()

-         return self

- 

      @property

      def owners(self):

          return [assoc.user for assoc in self.associations
@@ -246,21 +184,23 @@ 

          return cls.query.filter_by(user_hub=True).all()

  

      @classmethod

-     def create_user_hub(cls, session, username, fullname):

+     def create_user_hub(cls, username, fullname):

+         session = Session()

          hub = cls(name=username, user_hub=True)

          session.add(hub)

          hub_config = HubConfig(

              hub=hub, summary=fullname, avatar=username2avatar(username))

          session.add(hub_config)

  

-         hubs.defaults.add_user_widgets(session, hub, username, fullname)

+         hubs.defaults.add_user_widgets(hub, username, fullname)

  

-         user = User.by_username(username)

+         user = User.query.get(username)

          hub.subscribe(user, role='owner')

          return hub

  

      @classmethod

-     def create_group_hub(cls, session, name, summary, **extra):

+     def create_group_hub(cls, name, summary, **extra):

+         session = Session()

          hub = cls(name=name, user_hub=False)

          session.add(hub)

          # TODO -- do something else, smarter for group avatars
@@ -268,7 +208,7 @@ 

              hub=hub, summary=summary, avatar=username2avatar(name))

          session.add(hub_config)

  

-         hubs.defaults.add_group_widgets(session, hub, name, summary, **extra)

+         hubs.defaults.add_group_widgets(hub, name, summary, **extra)

          return hub

  

      def _get_auth_user_access_level(self, user):
@@ -577,18 +517,21 @@ 

          return cls.query.all()

  

      @classmethod

-     def get_or_create(cls, session, username, fullname):

+     def get_or_create(cls, username, fullname):

          if not username:

              raise ValueError("Must provide an username, not %r" % username)

+         self = cls.query.get(username)

+         if self is None:

+             self = cls.create(username, fullname)

+         return self

  

-         self = cls.by_username(username)

-         if not self:

-             self = cls(username=username, fullname=fullname)

-             session.add(self)

-             if not Hub.by_name(self.username):

-                 Hub.create_user_hub(session, self.username, self.fullname)

- 

-             session.commit()

+     @classmethod

+     def create(cls, username, fullname):

+         session = Session()

+         self = cls(username=username, fullname=fullname)

+         session.add(self)

+         if Hub.query.get(username) is None:

+             Hub.create_user_hub(username, fullname)

          return self

  

  
@@ -617,38 +560,29 @@ 

              username=username, visited_hub=visited_hub).first()

  

      @classmethod

-     def increment_visits(cls, session, username, visited_hub):

-         row = cls.get_or_create(session, username=username,

+     def increment_visits(cls, username, visited_hub):

+         row = cls.get_or_create(username=username,

                                  visited_hub=visited_hub)

          row.count += 1

-         session.commit()

  

      @classmethod

-     def _does_hub_exist(cls, session, hub=''):

-         return session.query(Hub).filter_by(name=hub).first() is not None

- 

-     @classmethod

-     def _does_user_exist(cls, session, user=''):

-         return session.query(User).filter_by(username=user).first() is not None

- 

-     @classmethod

-     def get_or_create(cls, session, username, visited_hub):

+     def get_or_create(cls, username, visited_hub):

          if not username:

              raise ValueError("Must provide an username, not %r" % username)

- 

          if not visited_hub:

              raise ValueError("Must provide an hub, not %r" % visited_hub)

- 

-         if not cls._does_hub_exist(session, hub=visited_hub) \

-                 or not cls._does_user_exist(session, user=username):

+         hub_exists = Hub.query.get(visited_hub) is not None

+         user_exists = User.query.get(username) is not None

+         if not hub_exists or not user_exists:

              raise ValueError("Must provide a hub/user that exists")

  

-         self = cls.get_visits_by_username_hub(username=username,

-                                               visited_hub=visited_hub)

-         if not self:

+         self = cls.query.filter_by(

+             username=username, visited_hub=visited_hub).first()

+         if self is None:

+             session = Session()

              self = cls(username=username, visited_hub=visited_hub)

              session.add(self)

-             session.commit()

+             session.flush()

          return self

  

  

file modified
+12 -6
@@ -21,8 +21,13 @@ 

  if "FEDMSG_CONFIG" not in os.environ:

      os.environ["FEDMSG_CONFIG"] = os.path.join(here, "fedmsg_test.cfg")

  

- import hubs.app     # noqa: E402

- import hubs.models  # noqa: E402

+ import hubs.app       # noqa: E402

+ import hubs.database  # noqa: E402

+ import hubs.models    # noqa: E402

+ 

+ 

+ # Remove the existing session if any.

+ hubs.database.Session.remove()

  

  

  class APPTest(unittest.TestCase):
@@ -32,27 +37,28 @@ 

          self.vcr = vcr.use_cassette(vcr_filename, record_mode='new_episodes')

          self.vcr.__enter__()

  

-         hubs.app.session = hubs.models.init(

+         hubs.database.init(

              hubs.app.fedmsg_config['hubs.sqlalchemy.uri'],

              create=True,

          )

+         self.session = hubs.database.Session()

+ 

          hubs.app.app.config['TESTING'] = True

  

          self.app = hubs.app.app.test_client()

          self.app.testing = True

-         self.session = hubs.app.session

  

          self.populate()

  

      def tearDown(self):

-         self.session.remove()

+         hubs.database.Session.remove()

          self.vcr.__exit__()

  

      def populate(self):

          for user in ['devyani7', 'dhrish', 'shalini', 'ralph', 'decause']:

              fullname = user.title()

              hubs.models.User.get_or_create(

-                 self.session, username=user, fullname=fullname)

+                 username=user, fullname=fullname)

              saved_notif = hubs.models.SavedNotification(

                  username=user, markup='foo', link='bar'

              )

file modified
+3 -6
@@ -100,18 +100,18 @@ 

  

          # Insert a new counter row

          vc = hubs.models.VisitCounter.get_or_create(

-             session=self.session, username=username, visited_hub=hub)

+             username=username, visited_hub=hub)

          # Make sure its init to 0

          self.assertEqual(vc.count, 0)

  

          # Increment counter and make sure its 1

          hubs.models.VisitCounter.increment_visits(

-             session=self.session, username=username, visited_hub=hub)

+             username=username, visited_hub=hub)

          self.assertEqual(vc.count, 1)

  

          # Delete the counter make sure the hub/user is still arround

          vc = hubs.models.VisitCounter.get_or_create(

-             session=self.session, username=username, visited_hub=hub)

+             username=username, visited_hub=hub)

          self.session.delete(vc)

          hub_obj = hubs.models.Hub.get(username)

          self.assertIsNotNone(hub_obj)
@@ -131,7 +131,6 @@ 

          hub = 'does-not-exist'

          self.assertRaises(ValueError,

                            hubs.models.VisitCounter.get_or_create,

-                           session=self.session,

                            username=username,

                            visited_hub=hub)

  
@@ -140,7 +139,6 @@ 

          # Make sure the table is empty of data

          self.assertRaises(ValueError,

                            hubs.models.VisitCounter.get_or_create,

-                           session=self.session,

                            username=username,

                            visited_hub=hub)

  
@@ -149,7 +147,6 @@ 

          # Make sure the table is empty of data

          self.assertRaises(ValueError,

                            hubs.models.VisitCounter.get_or_create,

-                           session=self.session,

                            username=username,

                            visited_hub=hub)

  

file modified
+6 -12
@@ -20,11 +20,9 @@ 

  log = logging.getLogger(__name__)

  

  

- def get_hub(name, load_config=False, session=None):

+ def get_hub(name, load_config=False):

      """ Utility shorthand to get a hub and 404 if not found. """

-     if session is None:

-         session = flask.g.db

-     query = session.query(Hub).filter(Hub.name == name)

+     query = Hub.query.filter(Hub.name == name)

      if load_config:

          query = query.options(joinedload(Hub.config))

      try:
@@ -33,25 +31,21 @@ 

          flask.abort(404)

  

  

- def query_hubs(querystring, session=None):

-     if session is None:

-         session = flask.g.db

-     query = session.query(Hub).join(HubConfig)

+ def query_hubs(querystring):

+     query = Hub.query.join(HubConfig)

      query = query.filter(or_(HubConfig.summary.ilike('%%%s%%' % querystring),

                               Hub.name.ilike('%%%s%%' % querystring)))

      return query.all()

  

  

- def get_widget_instance(hub, idx, session=None):

+ def get_widget_instance(hub, idx):

      """ Utility shorthand to get a widget and 404 if not found. """

-     if session is None:

-         session = flask.g.db

      try:

          idx = int(idx)

      except (TypeError, ValueError):

          flask.abort(400)

      try:

-         return session.query(Widget).join(Hub).filter(

+         return Widget.query.join(Hub).filter(

                  Hub.name == hub,

                  Widget.idx == idx,

              ).one()

file modified
+2 -3
@@ -106,14 +106,13 @@ 

      if str(visited_hub) != str(nickname):

          try:

              vc = hubs.models.VisitCounter.get_or_create(

-                 session=flask.g.db, username=nickname, visited_hub=visited_hub)

+                 username=nickname, visited_hub=visited_hub)

          except ValueError:  # this should never trip

              # flask will 405 if visited_hub is blank

              # @login_required forces flask.g.auth to be sets

              flask.abort(404)

          if flask.request.method == 'POST':

-             vc.increment_visits(session=flask.g.db,

-                                 username=nickname,

+             vc.increment_visits(username=nickname,

                                  visited_hub=visited_hub)

  

              return flask.jsonify({'count': vc.count})

file modified
+19 -15
@@ -9,12 +9,15 @@ 

  

  import fedora.client.fas2

  

+ import hubs.database

  import hubs.models

  from hubs.utils import get_fedmsg_config

  

  

  fedmsg_config = get_fedmsg_config()

- session = hubs.models.init(fedmsg_config['hubs.sqlalchemy.uri'], True, True)

+ hubs.database.init(

+     fedmsg_config['hubs.sqlalchemy.uri'], True, True)

+ db = hubs.database.Session()

  

  fasclient = fedora.client.fas2.AccountSystem(

      username=input('Your FAS username: '),
@@ -53,9 +56,9 @@ 

          fullname = user['human_name']

          print("Creating account for %r" % username)

          hubs_user = hubs.models.User.get_or_create(

-             session, username=username, fullname=fullname)

+             username=username, fullname=fullname)

  

-     session.commit()

+     db.commit()

  

      # Go back now and set up the groups...

      for user in users:
@@ -77,17 +80,18 @@ 

              if any([name.endswith(suffix) for suffix in suffix_blacklist]):

                  continue

  

-             hub = hubs.models.Hub.get_or_create(

-                 session,

-                 name=name,

-                 summary=summary,

-                 apply_rules=membership['apply_rules'],

-                 irc_channel=membership['irc_channel'],

-                 irc_network=membership['irc_network'],

-                 join_message=membership['joinmsg'],

-                 mailing_list=membership['mailing_list'],

-                 mailing_list_url=membership['mailing_list_url'],

-             )

+             hub = hubs.models.Hub.get(name)

+             if hub is None:

+                 hub = hubs.models.Hub.create_group_hub(

+                     name=name,

+                     summary=summary,

+                     apply_rules=membership['apply_rules'],

+                     irc_channel=membership['irc_channel'],

+                     irc_network=membership['irc_network'],

+                     join_message=membership['joinmsg'],

+                     mailing_list=membership['mailing_list'],

+                     mailing_list_url=membership['mailing_list_url'],

+                 )

  

              if hubs_user not in hub.subscribers:

                  hub.subscribe(hubs_user, role='subscriber')
@@ -97,4 +101,4 @@ 

                  if role['role_type'] in [u'administrator', u'sponsor']:

                      hub.subscribe(hubs_user, role='owner')

  

-     session.commit()

+     db.commit()

file modified
+23 -21
@@ -5,14 +5,16 @@ 

  

  import json

  

+ import hubs.database

  import hubs.models

  import hubs.widgets

  from hubs.utils import get_fedmsg_config

  

  

  fedmsg_config = get_fedmsg_config()

- 

- session = hubs.models.init(fedmsg_config['hubs.sqlalchemy.uri'], True, True)

+ hubs.database.init(

+     fedmsg_config['hubs.sqlalchemy.uri'], True, True)

+ db = hubs.database.Session()

  

  placekitten = "https://placekitten.com/g/320/320"

  
@@ -32,14 +34,14 @@ 

      fullname = 'Full Name Goes Here'

      print("Creating account for %r" % username)

      hubs.models.User.get_or_create(

-         session, username=username, fullname=fullname)

+         username=username, fullname=fullname)

  

- session.commit()

+ db.commit()

  

  # ############# Internationalizationteam

  hub = hubs.models.Hub(name='i18n', archived=True)

- session.add(hub)

- session.add(hubs.models.HubConfig(

+ db.add(hub)

+ db.add(hubs.models.HubConfig(

      hub=hub, summary='The Internationalization Team', avatar=placekitten))

  

  widget = hubs.models.Widget(
@@ -87,12 +89,12 @@ 

  hub.subscribe(hubs.models.User.by_username('ralph'), 'subscriber')

  

  

- session.commit()

+ db.commit()

  

  # ############# CommOps

  hub = hubs.models.Hub(name='commops')

- session.add(hub)

- session.add(hubs.models.HubConfig(

+ db.add(hub)

+ db.add(hubs.models.HubConfig(

      hub=hub, summary='The Fedora Community Operations Team'))

  

  widget = hubs.models.Widget(
@@ -137,12 +139,12 @@ 

  hub.subscribe(hubs.models.User.by_username('linuxmodder'), 'member')

  

  

- session.commit()

+ db.commit()

  

  # ############# Marketing team

  hub = hubs.models.Hub(name='marketing')

- session.add(hub)

- session.add(hubs.models.HubConfig(

+ db.add(hub)

+ db.add(hubs.models.HubConfig(

      hub=hub, summary='The Fedora Marketing Team'))

  

  widget = hubs.models.Widget(
@@ -194,12 +196,12 @@ 

  hub.subscribe(hubs.models.User.by_username('ralph'), 'subscriber')

  

  

- session.commit()

+ db.commit()

  

  # ############# Design team

  hub = hubs.models.Hub(name='designteam')

- session.add(hub)

- session.add(hubs.models.HubConfig(

+ db.add(hub)

+ db.add(hubs.models.HubConfig(

      hub=hub, summary='The Fedora Design Team'))

  

  widget = hubs.models.Widget(
@@ -247,13 +249,13 @@ 

  hub.subscribe(hubs.models.User.by_username('decause'), 'member')

  hub.subscribe(hubs.models.User.by_username('ralph'), 'subscriber')

  

- session.commit()

+ db.commit()

  

  

  # ############# Infra team

  hub = hubs.models.Hub(name='infrastructure')

- session.add(hub)

- session.add(hubs.models.HubConfig(

+ db.add(hub)

+ db.add(hubs.models.HubConfig(

      hub=hub, summary='The Fedora Infra Team'))

  

  widget = hubs.models.Widget(
@@ -293,12 +295,12 @@ 

  widget = hubs.models.Widget(plugin='feed', index=3, left=True)

  hub.widgets.append(widget)

  

- vc = hubs.models.VisitCounter().get_or_create(session, 'ralph', 'mrichard')

- hubs.models.VisitCounter().increment_visits(session, 'ralph', 'mrichard')

+ vc = hubs.models.VisitCounter.get_or_create('ralph', 'mrichard')

+ vc.increment_visits('ralph', 'mrichard')

  hub.subscribe(hubs.models.User.by_username('ralph'), 'owner')

  hub.subscribe(hubs.models.User.by_username('abompard'), 'owner')

  hub.subscribe(hubs.models.User.by_username('lmacken'), 'owner')

  hub.subscribe(hubs.models.User.by_username('nask0'), 'member')

  hub.subscribe(hubs.models.User.by_username('decause'), 'subscriber')

  

- session.commit()

+ db.commit()

file modified
+4 -5
@@ -15,18 +15,17 @@ 

  import hubs.app

  import hubs.models

  import hubs.widgets.base

+ from hubs.database import Session

  

  

- # get the DB session

- session = hubs.app.session

- 

+ db = Session()

  # Register widgets

  hubs.widgets.registry.register_list(hubs.app.app.config["WIDGETS"])

  

  

  def do_list(args):

      ''' List the different widget for which there is data cached. '''

-     for w_instance in session.query(hubs.models.Widget).all():

+     for w_instance in db.query(hubs.models.Widget).all():

          if not w_instance.enabled:

              continue

          widget = w_instance.module
@@ -42,7 +41,7 @@ 

          widget_instance = hubs.models.Widget.get(widget)

  

          if widget_instance is None:

-             widget_instances = session.query(hubs.models.Widget).filter_by(

+             widget_instances = db.query(hubs.models.Widget).filter_by(

                  plugin=widget).all()

          else:

              widget_instances = [widget_instance]

This brings the usage closer to what SQLAlchemy docs recommend.

It also avoids some import loops, and passing the session around all the
time when outside of Flask's request context.

See:
- http://docs.sqlalchemy.org/en/latest/orm/contextual.html#unitofwork-contextual
- http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#adding-additional-configuration-to-an-existing-sessionmaker

Looks like this needs to be rebased.

rebased onto 49de53360cfbbe0503cb83afe9e23b6d27059801

6 years ago

I think you do want to autocommit upon successful request. I'm actually not sure what will happen to the session if you do not commit. It seems likely the changes would be lost, or worse, would persist in the next request? I have no idea, but I think you do want to commit.

FWIW, Bodhi commits upon each successful request:

https://github.com/fedora-infra/bodhi/blob/3.0.0/bodhi/server/__init__.py#L44-L70

You might want to also do Session.remove() here.

It would be good to give this a docblock.

It would be good to give this a docblock.

I noticed that you are passing a db session around in a few methods. Instead of doing that, you could take advantage of this query object. I've been trying to convert Bodhi to work that way for a while since it's a bit cleaner.

It'd be good to document the create parameter as well.

Thanks! I'll fix all that and merge it.

rebased onto 154fad9

6 years ago

Pull-Request has been merged by abompard

6 years ago