1

I'm using SQLAlchemy in Python 3 and am confused why the following code works - it looks to me like what should be an object level variable is acting as a class variable. I have seen Why is instance variable behaving like a class variable in Python? which doesn't look related to my question.

I have the following declarations in a db module in which I create an instance of Base and set a query variable on it that points to the SessionFactory query_property()

import sqlalchemy as sa
import sqlalchemy.ext.declarative as sa_ed


Base = sa_ed.declarative_base()
engine = sa.create_engine('connection string')
session_factory = session or sa_orm.scoped_session(sa_orm.sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base.query = session_factory.query_property()  # make the query_property available in models for querying

My model classes are then declared as follows:

import db

class MyModel(db.Base):
    id = Column(Integer)
    # more model stuff

I can then run queries by accessing the query variable as follows:

return MyModel.query.filter(MyModel.id == 22).first()

This does work, but it looks as though the query variable exists at the class level and not at the object instance level as I am able to access it directly through the class.

What am I not understanding?

Community
  • 1
  • 1
user783836
  • 3,099
  • 2
  • 29
  • 34
  • 2
    I'm having a hard time understanding why you would be expecting `query` to _not_ be at the class level ... Perhaps you can edit your post and explain that better? – mgilson Jul 20 '16 at 07:02
  • I thought that `Base = sa_ed.declarative_base()` was creating an instance of the `Base` class I.e. an object of type `Base`. I see now that it is creating a class, which makes more sense – user783836 Jul 20 '16 at 11:12
  • Ahh ... Yes, I suppose that would make for some confusion. It's a somewhat abnormal pattern to return a class from a function (rather than a class instance), but it is definitely useful in some cases. – mgilson Jul 20 '16 at 15:21

1 Answers1

0

You put the query property on the parent class earlier:

Base.query = session_factory.query_property()  # make the query_property available in models for querying

So query is most definitely a member of a class (Base). And since MyModel inherits from Base, MyModel should also have a query member (due to the magic of inheritance).

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • Ah okay, so `Base` is a class not an object! I assumed by doing `Base = sa_ed.declarative_base()` I was creating an instance of the `Base` class i.e. a `Base` object. Looking at how I use `Base` I can see it would make more sense to be of type class – user783836 Jul 20 '16 at 11:09