Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLalchemy, why flask sets Base.query?

In the official Flask documentation for declarative use of SQLalchemy the following snipped is used:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:////tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

Now, I simply do not understand what the last line is doing. i.e. what does

Base.query = db_session.query_property()

Performs. Why that line is in there?

In my app I simply use db_session for every database operation. Now I have played a little with this, and found that, in the context of an interactive session or plain python script that line performs nothing!

For example this script prints True

import sqlalchemy as sq
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
eng = sq.create_engine('sqlite://')
Base = declarative_base()
db_session = scoped_session(sessionmaker(bind=eng))
Base.query = db_session.query_property()
Base.query
print(Base.query == None)

And so does this one:

import sqlalchemy as sq
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, scoped_session
eng = sq.create_engine('sqlite://')
Base = declarative_base(bind=eng)    ### the difference is here
db_session = scoped_session(sessionmaker(bind=eng))
Base.query = db_session.query_property()
Base.query
print(Base.query == None)

So I'm at a loss. The base object returned seem to have an __setattr__ that will disallow the setting of Base.query.

  • What that assignment should do?
  • And why my tests result in Base.query to be assigned with a None?
  • By default, Base does not have a query attribute, but then wouldn't be easier to simply do Base.query = None?

(P.S. This is all python 3.6)

like image 598
grochmal Avatar asked Feb 17 '17 23:02

grochmal


1 Answers

db_session.query_property is a descriptor that returns you a Query based on the class you accessed it from. For instance, if you have

class Foo(Base):
    pass

then Foo.query is a shorthand for db_session.query(Foo). Then, because it makes no sense to say db_session.query(Base), Base.query is naturally None.

like image 154
univerio Avatar answered Sep 28 '22 18:09

univerio