Skip to content

Instantly share code, notes, and snippets.

@RonnyPfannschmidt
Created April 8, 2014 17:17
Show Gist options
  • Save RonnyPfannschmidt/10158241 to your computer and use it in GitHub Desktop.
Save RonnyPfannschmidt/10158241 to your computer and use it in GitHub Desktop.
# current method
obj = session.query(Foo).get(id) # select * from foo where id=?
obj.bar = session.query(Bar).get(bar_id) # select * from bar where id=?
# what i want:
obj = session.query(Foo).get(id) # select * from foo where id=?
obj.bar = session.hollow(Bar, bar_id) # invented name, no query should happen until i use attributes of obj.bar
# what i want to avoid
obj = session.query(Foo).get(id) # select * from foo where id=?
obj.bar_id = bar_id
# why do i want to avoid?
"""
im dealing with a old where id fields are very commonly missued in `interesting` ways,
to remove that issue and the possibility to reintoroduce them
instead of id columns i always want to be able to work in terms of relationships and instances
btw, i'd love if foo.relationship would return a `hollow` instance as well, since for assignments i don't need a filled instance and db queries - just passing a id in disguise around after all
"""
@zzzeek
Copy link

zzzeek commented Apr 9, 2014

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Foo(Base):
    __tablename__ = 'foo'

    id = Column(Integer, primary_key=True)
    bar_id = Column(ForeignKey('bar.id'))
    bar = relationship("Bar")

class Bar(Base):
    __tablename__ = 'bar'

    id = Column(Integer, primary_key=True)
    data = Column(String)

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

sess = Session(e)

sess.add(Foo(id=1))
sess.add(Bar(id=1, data='bar'))
sess.commit()
sess.close()

f1 = sess.query(Foo).first()


b1 = Bar()

# this is easy to do, but trying to do this using as little private
# API as possible
from sqlalchemy import inspect

# setting .key here isn't necessarily stable long term
inspect(b1).key = Bar.__mapper__.identity_key_from_primary_key((1, ))
sess.add(b1)
sess.expire(b1)

f1.bar = b1
assert f1.bar.data == 'bar'
sess.commit()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment