2

I have a daemon running that generates data and writes it to my database using Flask. I'm now building an API service on top of that same data, and I'm hoping to reuse my same models, but this doesn't seem to work as expected. Here's what my model code looks like:

from sqlalchemy import BigInteger, Column, DateTime, Float, ForeignKey, Index, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
metadata = Base.metadata


class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(200), nullable=False, unique=True)
    ...

But then when I try to call it from the Flask App:

from flask.ext.sqlalchemy import SQLAlchemy
from models import User

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'some_mysql_connect_str'
db = SQLAlchemy(app)

...

def get_users_named_bob():
    return User.query.filter_by(name='bob')

I get: AttributeError: type object 'User' has no attribute 'query'

What's the best way of doing this?

Side note: I saw this question from about a year ago, but I'm hoping things have gotten better since then, since it seems a common use case.

Community
  • 1
  • 1
Eli
  • 36,793
  • 40
  • 144
  • 207

2 Answers2

2

I went looking through the Flask-SQLAlchemy code, and I don't think there's a good way to do what you want. Flask-SQLAlchemy wraps quite a few of SQLAlchemy's objects and expects that objects it handles inherits from it's Model class, not the vanilla SQLAlchemy one.

You can go a couple ways here, neither of which are great. First, you can use pure SQLAlchemy in Flask. It's a bit clunky since you won't get any of the niceties of Flask-SQLAlchemy and you'll have to handle marrying db sessions to Flask contexts yourself. Kinda ugly, but doable with some work.

The other option is to change your models over to Flask-SQLAlchemy and fix your daemon code to use those. My app runs a lot of cronjobs, and they all start something like this:

from myapp import app
from myapp.models import db, User

# do stuff with User, db

This can also be clunky because you'll have to make sure your daemon has the app package in its environment, plus making sure the app has the same config in all contexts can be tricky.

Maybe somebody else has a better idea, but I think you may be stuck with those options for now. I'm sorry I don't have a better answer for you.

Rachel Sanders
  • 5,734
  • 1
  • 27
  • 36
  • No worries. I came to the same conclusion myself. Was just hoping someone knew something I didn't. Thanks for taking the time to answer, anyway! – Eli Jul 09 '14 at 00:27
2

For anyone looking for this in the future, support is being added to Flask-SQLAlchemy for this: https://github.com/mitsuhiko/flask-sqlalchemy/issues/98

rachekalmir
  • 614
  • 1
  • 8
  • 17
  • Thanks! Really looking forward to the merge. Supposedly it's coming after the 2.1 release. After it's released, if you update here, I'd be happy to accept this as the right answer. – Eli Sep 23 '15 at 21:13