Take the 2-minute tour ×

I am using Flask for my python wsgi server, and sqlalchemy for all my database access.

I think I would like to use the Flask-Sqlalchemy extension in my application, but I do not want to use the declarative base class (db.Model), instead, I want to use the base from sqlalchemy.ext.declarative.

Does this defeat the entire purpose of using the extension?

My use case:

I would like the extension to help me manage sessions/engines a little better, but I would like to handle all models separately.

I actually wouldn't mind using the extension, but I want to write strict models. I am porting code from a non-flask application, and I will be pushing changes back to that project as I go. If flask-sqlalchemy allows me to cheat on Table metadata for instance, that is going to cause problems when the code is pushed back out. There are also portions of my code that do lots of type checking (polymorphic identities), and I also remember reading that type checking on Table is not recommended when using the extension.

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

SQLAlchemy themselves actually recommend you use the Flask wrapper (db.Model) for Flask projects. That being said I have used the declarative_base model in several of my Flask projects where it made more sense.

It does defeat the whole purpose of the SQLAlchemy class from flask-sqlalchemy.

Here's some sample code:

from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
import datetime

#set up sqlalchemy
engine = create_engine('postgresql://<username>:<password>@localhost/flask_database')
Base = declarative_base()
metadata = Base.metadata
metadata.bind = engine
Session = sessionmaker(bind=engine, autoflush=True)
session = Session()

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    api_owner_id = Column(Integer, ForeignKey('api.id'))
    email = Column(String(120), unique=True)
    username = Column(String(120), unique=True)
    first_name = Column(String(120))
    last_name = Column(String(120))
    business_name = Column(String(120))
    account_type = Column(String(60))
    mobile_phone = Column(String(120))
    street = Column(String(120))
    street2 = Column(String(120))
    city = Column(String(120))
    state = Column(String(120))
    zip_code = Column(String(120))
    country = Column(String(120))
    creation_date = Column(DateTime, default=datetime.datetime.now())
    password = Column(String(120))
    #github stuffs
    github_link = Column(Boolean, default=False)
    github_usn = Column(String(120))
    github_oauth_token = Column(String(160))
    #balanced stuffs
    balanced_account_uri = Column(String(120))
    ach_verified = Column(Boolean, default=False)
    active = Column(Boolean, default=True)
    profile_updated = Column(Boolean, default=False)
    account_balance = Column(Numeric(precision=10, scale=2), default=0.00)
    admin = Column(Boolean, default=False)
    devapp = relationship('DevApp', backref="user", lazy="dynamic")
    projects = relationship('Project', backref="user", lazy="dynamic")
    proposals = relationship('Proposal', backref="user", lazy="dynamic")
    transactions = relationship('Monies', backref="user", lazy="dynamic")

    def __repr__(self):
        return self.email
share|improve this answer
Your session/engine bit helped illustrate your answer. So, in my flask app, I need to pass around the session for usage. Do I need to clean up the session in any way after each use? (Maybe using app.do_teardown_xxx?) –  user2097818 Jul 24 '13 at 21:44
With the autoflush=True param in sessionmaker no cleanup is needed. user = User(email="nicholas.woodhams@gmail.com") session.add(user) session.commit() –  NickWoodhams Jul 24 '13 at 22:45
I don't plan to run this across multiple threads, but I will have discrete modules each using their own new session. I am planning to pass the sessionmaker. Those modules will make progressive updates. After committing each session instance, should there be any reason to worry about data integrity? (assuming my commits don't clobber each other). –  user2097818 Jul 25 '13 at 13:30
I'm pretty sure you'll have no issue with sessions clobbering eachother as long as each has it's own database connection. But I am not entirely sure so I would ask another question if it's a concern. Best –  NickWoodhams Jul 25 '13 at 19:13
add comment

You can have Flask-SQLAlchemy expose your own base Model instead of it's built-in one. Just subclass SQLAlchemy and override make_declarative_base.

from flask.ext.sqlalchemy import SQLAlchemy

class CustomAlchemy(SQLAlchemy):
    def make_declarative_base(self):
        base = declarative_base(...)
        return base

db = CustomAlchemy()
share|improve this answer
add comment

I'm actually using sqlalchemy in flask without using declarative base and I don't have any problems. You can always do that if you want to, there is no obligation to use object relational mapper, ORM is just one part of sqlalchemy. You can always just stay with alchemy sql expression language, define your tables in model objects, and define some methods there that will use expression language. I have a code like this (Model is the object i defined earlier), connect is a decorator which connects to db, it works fine for me.

def connect(func):
    eng = create_engine(app.config["DATABASE"])
    def wrapped(*args,**kwargs):
        with closing(eng.connect()) as con:
            result = con.execute(func(*args,**kwargs))
        return result
    return wrapped

class User_(Model):
    def __init__(self):
        self.metadata = MetaData()
        self.structure = Table("users", self.metadata,

    def get_hashed_pass(self,username):
        """  """
        t = self.structure
        s = select([t.c.password]).where(t.c.username == str(username))
        return s
 #other methods follow

Flask's documentation concerning alchemy explicitly says that it is completely okay to do that:

If you just want to use the database system (and SQL) abstraction layer you basically only need the engine

P.S. Oh, and one more thing, they say in the docs that if you want to get started quickly you're better off using extension, but I'm personally not so sure about that, if you're like me and you feel more familiar with the sql queries rather then with ORM, it may be much easier for you to get started quickly without extension.

share|improve this answer
It took me a while to get your meaning (I didn't see the connect decorator on the method). Using a session inside of a model was going to be my next question! –  user2097818 Jul 25 '13 at 14:28
add comment

Your Answer


