Skip to content

Instantly share code, notes, and snippets.

# filter
# * メソッドをつなげて利用できる。
# => SELECT * From entries WHERE id = 1 AND text = "entry"
Entry.query.filter(Entry.id == 1).filter(Entry.text == "entry").all()
# filter_by
# * filterのシンタックスシュガー
Entry.query.filter_by(id=1, text="entry").all()
# get
# relationship('Comment', lazy="subquery")
# ------------------------------------------
# * 取得タイミング
# * Entryを取得後、EntryのId列だけを取得して、そのId列のCommentのみを取得
#
# entry = Entry.query.filter_by(id=1).first() <- タイミングここ
# entry.comments
#
# * 発行SQL
# 1. SELECT * FROM entries WHERE entries.id = 1 LIMIT 1
# relationship('Comment', lazy="joined")
# ------------------------------------------
# * 取得タイミング
# * 親と子をJoinしたSQLを発行
# * ちなみに joinedload = eagarload は SQLAlchemyでは異音同義語(シノニム)
#
# entry = Entry.query.filter_by(id=1).first() <- タイミングここ
# entry.comments
#
# * 発行SQL
# relationship('Comment', lazy="immediate")
# ------------------------------------------
# * 取得タイミング
# * 親のモデルがロードされたタイミング一緒にSQL発行
# * lazy="select"とはタイミングが違うだけで発行してるSQLは一緒
#
# entry = Entry.query.filter_by(id=1).first() <- タイミングここ
# entry.comments
#
# * 発行SQL
# relationship('Comment', lazy="select") (デフォルト)
# ------------------------------------------
# * 取得タイミング
# * プロパティにアクセスしたタイミング
#
# entry = Entry.query.filter_by(id=1).first()
# entry.comments # <- タイミングここ
#
# * 発行SQL
#
class Entry(Base):
__tablename__ = 'entries'
id = Column(Integer, primary_key=True)
text = Column(String(200))
created_at = Column(DateTime, default=datetime.now, nullable=False)
comments = relationship('Comment', backref="entry", lazy="select") #<= lazyパラメータ
entry = Entry.query.get(1)
entry.comments[0] # => <__main__.Comment object at 0x10184acd0>
comment = Comment.query.get(1)
comment.entry # => <__main__.Entry object at 0x101841a10>
# EngineをDB毎に用意
dsn1 = 'mysql://testuser:testpass@localhost/test'
engine1 = create_engine(dsn1, convert_unicode=True, echo=False)
dsn2 = 'mysql://testuser:testpass@localhost/test2'
engine2 = create_engine(dsn2, convert_unicode=True, echo=False)
Base = declarative_base()
db_session = scoped_session(sessionmaker(twophase=True))
Base.query = db_session.query_property()
class Entry(Base):
__tablename__ = 'entries'
id = Column(Integer, primary_key=True)
text = Column(String(200))
created_at = Column(DateTime, default=datetime.now, nullable=False)
comments = relationship('Comment', backref="entry",
primaryjoin="Entry.id==Comment.entry_id", # <- ここ
foreign_keys="Comment.entry_id") # <- ここ
class Entry(Base):
__tablename__ = 'entries'
id = Column(Integer, primary_key=True)
text = Column(String(200))
created_at = Column(DateTime, default=datetime.now, nullable=False)
comments = relationship('Comment', backref="entry") # Commentテーブルへのリレーション
class Comment(Base):
__tablename__ = 'comments'