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.

Reply via email to