Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using flask-sqlalchemy without the subclassed declarative base

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.

like image 759
user2097818 Avatar asked Jul 24 '13 18:07

user2097818


People also ask

What is the use of declarative base in SQLAlchemy?

The declarative_base() function is used to create base class. This function is defined in sqlalchemy.

Can I use Flask-SQLAlchemy without Flask?

All you need is to create a db connection and import your model to either flask, or non-flask app. I'd simply put the model in 'models.py' so (really just move the above from the flask main .

What is SQLAlchemy ext declarative?

function sqlalchemy.ext.declarative. has_inherited_table(cls) Given a class, return True if any of the classes it inherits from has a mapped table, otherwise return False. This is used in declarative mixins to build attributes that behave differently for the base class vs. a subclass in an inheritance hierarchy.

Can I use SQLAlchemy with Flask?

Flask-SQLAlchemy is a Flask extension that makes using SQLAlchemy with Flask easier, providing you tools and methods to interact with your database in your Flask applications through SQLAlchemy. In this tutorial, you'll build a small student management system that demonstrates how to use the Flask-SQLAlchemy extension.


2 Answers

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()
like image 119
davidism Avatar answered Oct 14 '22 12:10

davidism


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"])
    @wraps(func)
    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):
        Model.__init__(self)
        self.metadata = MetaData()
        self.structure = Table("users", self.metadata,
                               Column("id",Integer,primary_key=True),
                               Column("username",VARCHAR(64)),
                               Column("password",TEXT),
                               Column("email",VARCHAR(100)),
                               Column("about_me",TEXT),
                               Column("deadline",DATETIME),
                               Column("points",INTEGER)),
                               Column("date_created",DATETIME))

    @connect
    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.

like image 27
Pawel Miech Avatar answered Oct 14 '22 13:10

Pawel Miech