What's the difference between Model.query and session.query(Model) in SQLAlchemy?

PythonSqlalchemy

Python Problem Overview


I'm a beginner in SQLAlchemy and found query can be done in 2 method:

Approach 1:

DBSession = scoped_session(sessionmaker())
class _Base(object):
    query = DBSession.query_property()

Base = declarative_base(cls=_Base)

class SomeModel(Base):
    key   = Column(Unicode, primary_key=True)
    value = Column(Unicode)

# When querying
result = SomeModel.query.filter(...)

Approach 2

DBSession = scoped_session(sessionmaker())
Base = declarative_base()

class SomeModel(Base):
    key   = Column(Unicode, primary_key=True)
    value = Column(Unicode)

# When querying
session = DBSession()
result = session.query(SomeModel).filter(...)

Is there any difference between them?

Python Solutions


Solution 1 - Python

In the code above, there is no difference. This is because, in line 3 of the first example:

  • the query property is explicitly bound to DBSession
  • there is no custom Query object passed to query_property

As @petr-viktorin points out in the answer here, there must be a session available before you define your model in the first example, which might be problematic depending on the structure of your application.

If, however, you need a custom query that adds additional query parameters automatically to all queries, then only the first example will allow that. A custom query class that inherits from sqlalchemy.orm.query.Query can be passed as an argument to query_property. This question shows an example of that pattern.

Even if a model object has a custom query property defined on it, that property is not used when querying with session.query, as in the last line in the second example. This means something like the first example the only option if you need a custom query class.

Solution 2 - Python

An answer (here) to a different SQLAlchemy question might help. That answer starts with: > You can use Model.query, because the Model (or usually its base class, especially in cases where declarative extension is used) is assigned Session.query_property. In this case the Model.query is equivalent to Session.query(Model).

Solution 3 - Python

I see these downsides to query_property:

  • You cannot use it on a different Session than the one you've configured (though you could always use session.query then).
  • You need a session object available before you define your schema.

These could bite you when you want to write tests, for example.

Also, session.query fits better with how SQLAlchemy works; query_property looks like it's just added on top for convenience (or similarity with other systems?). I'd recommend you stick to session.query.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCosmia LunaView Question on Stackoverflow
Solution 1 - PythonglyphobetView Answer on Stackoverflow
Solution 2 - PythonRobertView Answer on Stackoverflow
Solution 3 - PythonPetr ViktorinView Answer on Stackoverflow