On Sat, Sep 29, 2018 at 11:18 AM seaders <seader...@gmail.com> wrote: > > Yes, that's exactly what I want. No queries to the database, at any time > exactly. > > However, doing that, I get > > sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: > sport [SQL: 'INSERT INTO sport ...] (Background on this error at: > http://sqlalche.me/e/e3q8) > > I haven't created, nor - if possible - really want to create any tables for > the tests. But it looks like doing s.flush() is trying to write to the > database?
yes, flush writes to the database. SQLAlchemy is a database access tool. If you're trying to build some system of integers and objects connected to each other in some way that *resembles* a relational database but doesnt actually use one, the ORM is not in that business. There's an "index" recipe at https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/SessionIndexing that allows you to look up objects by different fields in memory, but it has very little to do with the ORM, it's just a set of lookups. There are a lot of techniques that can be used to test ORM models, including some that use "mock" queries, check out the example at https://bitbucket.org/zzzeek/pycon2014_atmcraft/src/master/atmcraft/tests/test_views_mockdb.py. All the Session.query() you see there is done using mocks. maybe that can spark some ideas for how to do what you need even though it is quite different (doesn't use a DB though). > > On Saturday, September 29, 2018 at 3:18:24 PM UTC+1, Mike Bayer wrote: >> >> On Sat, Sep 29, 2018 at 7:34 AM seaders <sead...@gmail.com> wrote: >> > >> > Yep, that helps, nearly doing what I want. >> > >> > I have a "from_flat_json" function in my base class, so that's a perfect >> > place to add the `session.enable_relationship_loading` bit for any created >> > objects - that's now working, which is great. >> > >> > Only thing that's not wanted / right just yet is the ".commit()". If >> > possible, I'd even prefer to not have that in the system, but without >> > that, a1 isn't available for lookup, i.e. (using your example), >> > >> > a1 = A(id=1) >> > s.add(a1) >> > s.enable_relationship_loading(a1) >> > >> > b1 = B(a_id=1) >> > s.add(b1) >> > s.enable_relationship_loading(b1) >> > assert b1.a is a1 >> >> So what you have above would literally be SQLAlchemy doing the >> querying in memory without even using the database, because at no >> point above is anything being sent to the database. You don't need >> to "commit" the transaction, for your local work, you only need to >> flush() so that the row is present in the DB within the transaction: >> >> a1 = A(id=1) >> s.add(a1) >> s.flush() >> >> b1 = B(a_id=1) >> s.add(b1) >> s.enable_relationship_loading(b1) >> assert b1.a is a1 >> >> >> >> >> >> > >> > >> > >> > On Saturday, September 29, 2018 at 3:33:10 AM UTC+1, Mike Bayer wrote: >> >> >> >> >> >> yes that's what those two flags are doing. the way the ORM is >> >> designed, it wants you to be setting comp.sport = sport, not >> >> comp.sport_id = id, but there's a fair degree of special features >> >> these days that allow people to work the other way since it is so >> >> commonly requested, which are specifically what those two flags are >> >> for. >> >> >> >> an overview of the situation is at >> >> https://docs.sqlalchemy.org/en/latest/faq/sessions.html#i-set-the-foo-id-attribute-on-my-instance-to-7-but-the-foo-attribute-is-still-none-shouldn-t-it-have-loaded-foo-with-id-7, >> >> which is probably the first FAQ question we've ever had. The API >> >> features that correspond to load_on_pending and load_pending are the >> >> load_on_pending relationship flag: >> >> https://docs.sqlalchemy.org/en/latest/orm/relationship_api.html?highlight=load_on_pending#sqlalchemy.orm.relationship.params.load_on_pending >> >> , and enable_relationship_loading at >> >> https://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.enable_relationship_loading, >> >> which does the same thing with a different scope, that is, for >> >> individual objects rather than an entire mapping. >> >> >> >> both APIs do a similar thing, it's just that load_on_pending is set at >> >> the level of the class mapping on the relationship, whereas >> >> enable_relationship_loading you can just enable for any individual >> >> object without any change to the mapping which may be better for >> >> running tests. >> >> >> >> since I never use these I feel I had to test them out to make sure I'm >> >> not mis-characterizing, so it looks like this. here is >> >> load_on_pending: >> >> >> >> class A(Base): >> >> __tablename__ = 'a' >> >> >> >> id = Column(Integer, primary_key=True) >> >> bs = relationship("B", backref=backref("a", load_on_pending=True)) >> >> >> >> >> >> class B(Base): >> >> __tablename__ = 'b' >> >> id = Column(Integer, primary_key=True) >> >> a_id = Column(ForeignKey("a.id")) >> >> >> >> >> >> s = Session(e) >> >> >> >> a1 = A(id=1) >> >> s.add(a1) >> >> s.commit() >> >> >> >> b1 = B(a_id=1) >> >> s.add(b1) # note you have to add b1 to the session for it to be >> >> "pending" >> >> assert b1.a is a1 >> >> >> >> Here is enable_relationship_loading: >> >> >> >> class A(Base): >> >> __tablename__ = 'a' >> >> >> >> id = Column(Integer, primary_key=True) >> >> bs = relationship("B", backref="a") >> >> >> >> >> >> class B(Base): >> >> __tablename__ = 'b' >> >> id = Column(Integer, primary_key=True) >> >> a_id = Column(ForeignKey("a.id")) >> >> >> >> >> >> a1 = A(id=1) >> >> s.add(a1) >> >> s.commit() >> >> >> >> b1 = B(a_id=1) >> >> s.enable_relationship_loading(b1) # note you *don't* have to add to >> >> the session for this >> >> assert b1.a is a1 >> >> >> >> you can also add b1 to the session at any time above. >> >> >> >> hope this helps. >> >> >> >> >> >> >> >> >> >> >> >> >> >> > >> >> > >> >> > -- >> >> > 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+...@googlegroups.com. >> >> > To post to this group, send email to sqlal...@googlegroups.com. >> >> > Visit this group at https://groups.google.com/group/sqlalchemy. >> >> > For more options, visit https://groups.google.com/d/optout. >> > >> > -- >> > 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+...@googlegroups.com. >> > To post to this group, send email to sqlal...@googlegroups.com. >> > Visit this group at https://groups.google.com/group/sqlalchemy. >> > For more options, visit https://groups.google.com/d/optout. > > -- > 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 post to this group, send email to sqlalchemy@googlegroups.com. > Visit this group at https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- 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 post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.