Thanks for the thoughts. I'm going to digest, read docs, and experiment.
On Wed, Feb 12, 2020 at 8:52 AM Mike Bayer <mike...@zzzcomputing.com> wrote: > > > On Tue, Feb 11, 2020, at 11:41 PM, Rob Rosenfeld wrote: > > Hi All, > > I am using Flask-SQLAlchemy on a legacy database. My SQLA classes / > tables are setup using declarative base and autoload. In addition to using > the class to access persisted data, I also use plain old Python to enrich > them with ephemeral data. > > Every time I load a User object, I'd like the instance for that particular > object / row to retain its plain old python instance data. > > My understanding is that Flask-SQLAlchemy will by default use a separate > scoped_session for each request. And that means at the end of the request > session and user will go out of scope. So in the next request to > /users/Bob will instantiate a new User object whose will be reinitialized . > . . each time I make this request I will be told it was "asked 1 time". > > Alternately, if I call /users_alt/Bob, then second time I call a > DetachedInstanceError will be raised when I attempt to read user.owners. > > I suspect there's a pattern used to accomplish what I want to do, but I > have not tried the right Google search. Any recommendations on how to > approach this or searches to try / doc sections to read? The state I'm > storing in times_name_read_since_launch is actually complex enough that I > don't want to persist it and have to keep that dependent state synchronized. > > Alternately is there a way for me to reattach a SQLA object to the current > requests' session? Then, ideally, I could get updates from the database to > User or Owner objects, but retain my ephemeral state in the plain old > python. > > > you can get a plain reattach without it emitting any SQL using > session.add(): > > > session.add(detached_object) > > > however, if you're not sure if detached_object's primary key might have > been loaded already, you would want to use session.merge() instead. if > your object has no changes on it you can add load=False which will avoid a > SQL round trip. > > > > > Thanks for the help, > Rob > > from flask import Flask > from flask_sqlalchemy import SQLAlchemy > from sqlalchemy import MetaData > from sqlalchemy import orm > > app = Flask(__name__) > app.config['SQLALCHEMY_DATABASE_URI'] = connection_string > db = SQLAlchemy(app) > > > class Owner(db.Model): > __table__ = db.Table('Owners', MetaData(), autoload=True, > autoload_with=db.engine) > > > class User(db.Model): > __table__ = db.Table('users', MetaData(), autoload=True, autoload_with > =db.engine) > owners = db.relationship('Owner', primaryjoin= > "foreign(User.userId)==remote(Owner.userId)", uselist=True, > backref=db.backref('user', uselist=False)) > > users_seen = dict() > > @orm.reconstructor > def init_on_load(self): > self.times_name_read_since_launch = 0 > > @classmethod > def lookup_by_name(cls, name): > user_ = User.users_seen.get(name) > if user_ is None: > user_ = User.query.filter(User.UserName == name).one() > return user_ > > @classmethod > def store_by_name(cls, user_): > if user_.UserName not in User.users_seen: > User.users_seen[user_.UserName] = user_ > > @property > def name(self): > self.times_name_read_since_launch += 1 > return self.UserName > > > @app.route("/users/<string:name>") > def user(name): > user_ = User.query.filter(User.UserName == name).one() > return "{} with {} - asked {} times".format(user_.name, user_.owners, > user_.times_name_read_since_launch) > > > @app.route("/users_alt/<string:name>") > def user_alt(name): > user_ = User.lookup_by_name(name) > User.store_by_name(user_) > owners = None > if user_.times_name_read_since_launch > 0: > # don't lazy load addresses the first request, simulates more > complex actual behavior desired > owners = user_.owners > return "{} with {} - asked {} times".format(user_.name, owners, user_. > times_name_read_since_launch) > > > db.create_all() > > > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sqlalchemy/66717a53-d81b-4cce-be68-601c5d673284%40googlegroups.com > <https://groups.google.com/d/msgid/sqlalchemy/66717a53-d81b-4cce-be68-601c5d673284%40googlegroups.com?utm_medium=email&utm_source=footer> > . > > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > You received this message because you are subscribed to a topic in the > Google Groups "sqlalchemy" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/sqlalchemy/NS4PbZ2nLwU/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > sqlalchemy+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sqlalchemy/31e0db24-1a1a-4099-8510-d9568fb97ca0%40www.fastmail.com > <https://groups.google.com/d/msgid/sqlalchemy/31e0db24-1a1a-4099-8510-d9568fb97ca0%40www.fastmail.com?utm_medium=email&utm_source=footer> > . > -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/CAHUdipkbRTF8m2eZhAr9cpdu1oT9v%3Dw3oMttETrsLfK%2Bzwojxg%40mail.gmail.com.