Code Monkey home page Code Monkey logo

flask-sqlalchemy's Introduction

Flask-SQLAlchemy

Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application. It aims to simplify using SQLAlchemy with Flask by providing useful defaults and extra helpers that make it easier to accomplish common tasks.

Pallets Community Ecosystem

Important

This project is part of the Pallets Community Ecosystem. Pallets is the open source organization that maintains Flask; Pallets-Eco enables community maintenance of Flask extensions. If you are interested in helping maintain this project, please reach out on the Pallets Discord server.

A Simple Example

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///example.sqlite"

class Base(DeclarativeBase):
  pass

db = SQLAlchemy(app, model_class=Base)

class User(db.Model):
    id: Mapped[int] = mapped_column(primary_key=True)
    username: Mapped[str] = mapped_column(unique=True)

with app.app_context():
    db.create_all()

    db.session.add(User(username="example"))
    db.session.commit()

    users = db.session.execute(db.select(User)).scalars()

flask-sqlalchemy's People

Contributors

coburnjoe avatar dasich avatar davidism avatar dependabot-preview[bot] avatar dependabot[bot] avatar greyli avatar hugovk avatar immunda avatar jeff-99 avatar jparise avatar jqxl0205 avatar justanr avatar lbeaufort avatar martijnvermaat avatar mgax avatar minisotm avatar miracle2k avatar mitsuhiko avatar mvantellingen avatar pamelafox avatar plaes avatar pre-commit-ci[bot] avatar rsyring avatar s0undt3ch avatar simonsapin avatar svenstaro avatar thiefmaster avatar thrawny avatar trollefson avatar yuxiaoy1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flask-sqlalchemy's Issues

No way to use a pre-existing metadata object with flask-sqlalchemy

I would prefer not to couple my modeling code to my web application. My preferred technique is to create a metadata in the same module as my model definitions, passing that later to table definitions. This lets me use the same module definitions in external scripts without a lot of overhead.

Support __iter__ on Pagination instances.

I never remember to call .items, and I was just reminded of this when getting a new developer spun up. Instead of:

for obj in MyModel.query.paginate(1).items: pass

I expect:

for obj in MyModel.query.paginate(1): pass

... because SQLAlchemy's query API does this everywhere. This fails, because a Pagination instance is not iterable.

Odd session behavior

The assertion in the following code fails:

from flask import Flask
from flaskext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)

db.create_all()
test = User(username='test')
db.session.add(test)
assert len(db.session.query(User).all()) == 1

The equivalent code written using only SQLAlchemy works:

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

engine = create_engine('sqlite:///:memory:')
Base = declarative_base()
session = scoped_session(sessionmaker(bind=engine))()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(80), unique=True)

Base.metadata.create_all(bind=engine)
test = User(username='test')
session.add(test)
assert len(session.query(User).all()) == 1

One-to-One Relationship Issues

Hi,

I've just setup a new virtualenv and pulled the latest Flask-SQLAlchemy module from pip but I'm having issues when trying to configure a one-to-one relationship between two objects like so:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)

class Parent(db.Model):
    __tablename__ = 'parents'
    id = db.Column(db.Integer, primary_key=True)
    child_id = db.Column(db.Integer, db.ForeignKey("children.id"))
    child = db.relationship("Child", backref=db.backref("parent", uselist=False))

class Child(db.Model):
    __tablename__ = 'children'
    id = db.Column(db.Integer, primary_key=True)

db.create_all()

parent = Parent()
child = Child()

This code errors with the following error:

ArgumentError: Could not determine join condition between parent/child tables on relationship Parent.child.  Specify a 'primaryjoin' expression.  If 'secondary' is present, 'secondaryjoin' is needed as well.

According to the SQLAlchemy documentation (http://docs.sqlalchemy.org/en/latest/orm/relationships.html#one-to-one) the above should work without issue.

It is worth noting that I have a previous virtual-environment with Flask-SQLAlchemy before the namespace was changed from flaskext.sqlalchemy to flask_sqlalchemy and the above code runs fine using that.

Cheers,
David.

paginate() not working on relationships

When querying using a mapped class or instance, the query_class is flaskext.sqlalchemy.BaseQuery and i get the expected exception with the following:

user.query.paginate()
TypeError: paginate() takes at least 2 arguments (1 given)

But when using a relationship configured on a class or instance query_class is None and paginate() not available.

user.roles.paginate()
AttributeError: 'AppenderQuery' object has no attribute 'paginate'

init_app() of class SQLAlchemy

i think, in the init_app() of class SQLAlchemy, add the following clause would be better:

self.app = app

because, if some create db as following:
db = SQLAlchemy()
db.init_app()

then, db.app is not set, db.get_app would use ctx.app

before_models_committed signal never sent

It seems the before_models_committed is never sent.

Looking in depth in this piece of code:

class _SignalTrackingMapperExtension(MapperExtension):

def after_delete(self, mapper, connection, instance):
    return self._record(mapper, instance, 'delete')

def after_insert(self, mapper, connection, instance):
    return self._record(mapper, instance, 'insert')

def after_update(self, mapper, connection, instance):
    return self._record(mapper, instance, 'update')

def _record(self, mapper, model, operation):
    pk = tuple(mapper.primary_key_from_instance(model))
    orm.object_session(model)._model_changes[pk] = (model, operation)
    return EXT_CONTINUE

class _SignallingSessionExtension(SessionExtension):

def before_commit(self, session):
    d = session._model_changes
    if d:
        before_models_committed.send(session.app, changes=d.values())
    return EXT_CONTINUE

def after_commit(self, session):
    d = session._model_changes
    if d:
        models_committed.send(session.app, changes=d.values())
        d.clear()
    return EXT_CONTINUE

def after_rollback(self, session):
    session._model_changes.clear()
    return EXT_CONTINUE

the problem seems like this:

  • In the case of after_commit the flow i can see is:
    • _record method called
    • session._model_changes filled
    • after_commit called
    • d is filled with _model_changes
    • the signal is sent
  • In the case of before_commit, the flow is:
    • before_commit is called
    • d in empty so no signal is sent
    • _record is called and _model_changes filled
    • but it's to late...

but i can't figure out how this happen

No documentation for creating application in multiple modules

While Flask itself seem to have quite a heavy emphasis on splitting ones' application into several module, it does not seem like flask-sqlalchemy has any support for that.

My gut feeling is that I'm missing something obvious, but I might be mistaken. Either way, it should be documented.

drivername not found or defined

I don't know if this is a config issue or a bug at this point.
Flast-SQLAlchemy is used as part of mead project.

** My setup is in a virtual environment:

** python version
(mead_dev)seth@dharma:~/Code/python/mead_dev/mead$ python -V
Python 2.7.2+

** Please take a look at the stack dump below. Object name seem not to be defined.
Looked @ the code and don't have much context.

_EngineConnector.get_uri() does some binding, which fails to be defined properly and is not 'sane'.
Hence an invalid uri is returned. Also digging further it seems that the binding to a db-engine is not defined. So maybe this is a config issues?

** Maybe you can shed some light on this?

[stack trace](mead_dev)seth@dharma:~/Code/python/mead_dev/mead$ ./run_server.py 
Traceback (most recent call last):
  File "./run_server.py", line 4, in <module>
    from mead import app
  File "/home/seth/Code/python/mead_dev/mead/mead/**init**.py", line 66, in <module>
    import mead.core.views.content
  File "/home/seth/Code/python/mead_dev/mead/mead/core/views/content.py", line 10, in <module>
    from available import defaults
  File "/home/seth/Code/python/mead_dev/mead/mead/core/views/available.py", line 22, in <module>
    defaults.update(dict(pages = Page.query.all()))
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/Flask_SQLAlchemy-0.15-py2.7.egg/flaskext/sqlalchemy.py", line 386, in **get**
    return type.query_class(mapper, session=self.sa.session())
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7.egg/sqlalchemy/orm/scoping.py", line 53, in **call**
    return self.registry()
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/SQLAlchemy-0.7.3-py2.7.egg/sqlalchemy/util/_collections.py", line 877, in __call__
    val = self.registry.value = self.createfunc()
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/Flask_SQLAlchemy-0.15-py2.7.egg/flaskext/sqlalchemy.py", line 191, in **init**
    bind=db.engine,
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/Flask_SQLAlchemy-0.15-py2.7.egg/flaskext/sqlalchemy.py", line 719, in engine
    return self.get_engine(self.get_app())
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/Flask_SQLAlchemy-0.15-py2.7.egg/flaskext/sqlalchemy.py", line 736, in get_engine
    return connector.get_engine()
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/Flask_SQLAlchemy-0.15-py2.7.egg/flaskext/sqlalchemy.py", line 428, in get_engine
    self._sa.apply_driver_hacks(self._app, info, options)
  File "/home/seth/Code/python/mead_dev/local/lib/python2.7/site-packages/Flask_SQLAlchemy-0.15-py2.7.egg/flaskext/sqlalchemy.py", line 679, in apply_driver_hacks
    if info.drivername == 'mysql':
AttributeError: 'NoneType' object has no attribute 'drivername'

initialization fails on Jython

as discussed on IRC:

Jython 2.5.3b1 (2.5:5fa0a5810b25, Feb 22 2012, 12:39:02) 
[OpenJDK 64-Bit Server VM (Oracle Corporation)] on java1.7.0_03-icedtea
Type "help", "copyright", "credits" or "license" for more information.
>>> from flaskext.sqlalchemy import SQLAlchemy
>>> SQLAlchemy()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/fnd/jython/Lib/site-packages/flaskext/sqlalchemy.py", line 606, in __init__
    _include_sqlalchemy(self)
  File "/home/fnd/jython/Lib/site-packages/flaskext/sqlalchemy.py", line 81, in _include_sqlalchemy
    setattr(obj, key, getattr(module, key))
AttributeError: 'module' object has no attribute 'sys'

(tested with Jython v2.5.2 and v2.5.3b1)

Wrapping that line in a try ... except: pass seems to work fine (debugging shows that "sys" is the only key to throw that error).

some more data based on our IRC conversation:

Jython 2.5.3b1 (2.5:5fa0a5810b25, Feb 22 2012, 12:39:02) 
[OpenJDK 64-Bit Server VM (Oracle Corporation)] on java1.7.0_03-icedtea
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlalchemy
>>> sqlalchemy.__all__
['BLOB', 'BOOLEAN', 'BigInteger', 'Binary', 'Boolean', 'CHAR', 'CLOB',
'CheckConstraint', 'Column', 'ColumnDefault', 'Constraint', 'DATE',
'DATETIME', 'DDL', 'DECIMAL', 'Date', 'DateTime', 'DefaultClause', 'Enum',
'FLOAT', 'FetchedValue', 'Float', 'ForeignKey', 'ForeignKeyConstraint',
'INT', 'INTEGER', 'Index', 'Integer', 'Interval', 'LargeBinary',
'MetaData', 'NCHAR', 'NUMERIC', 'NVARCHAR', 'Numeric', 'PassiveDefault',
'PickleType', 'PrimaryKeyConstraint', 'REAL', 'SMALLINT', 'Sequence',
'SmallInteger', 'String', 'TEXT', 'TIME', 'TIMESTAMP', 'Table', 'Text',
'ThreadLocalMetaData', 'Time', 'TypeDecorator', 'Unicode', 'UnicodeText',
'UniqueConstraint', 'VARCHAR', 'alias', 'and_', 'asc', 'between',
'bindparam', 'case', 'cast', 'collate', 'create_engine', 'delete', 'desc',
'distinct', 'engine_from_config', 'except_', 'except_all', 'exists',
'extract', 'func', 'insert', 'intersect', 'intersect_all', 'join',
'literal', 'literal_column', 'modifier', 'not_', 'null', 'or_',
'outerjoin', 'outparam', 'over', 'select', 'subquery', 'sys', 'text',
'tuple_', 'type_coerce', 'union', 'union_all', 'update']

Inject BaseQuery into the SQLAlchemy object and relationships

Currently lazy=dynamic relationships return a sqlalchemy query and not a Flask-SQLAlchemy query. The methods on SQLAlchemy() should inject that automatically with the query_class parameter.

That parameter is also supported for backref and relationship, even though the docs do not mention that.

mysql pool recycle default

there is default for mysql driver in flask-sqlalchemy
options.setdefault('pool_recycle', 7200)

Most servers will timeout client connection in 1 hour IMO it's better to use this as a default value and let people change it to longer times when appropriate.

(....there is another caveat right now - if your mysql server got restarted there is nothing that would catch exception and try to reconnect to serve current request, I wonder if that exception would be possible to catch in lib, not inside of the application code)

Version 0.10 tag and package ?

Hi,

First, thank you for developing Flask, I'm having a lot of fun playing with it.

I see that the doc mentions a 0.10 version, and so does the setup.py file. However, the corresponding tag and pypi packages seems to be missing. Is this intended ?

improve the Pagination class with neighbours

I already use a Pagination class with SQLAlchemy and werkzeug.
The implementation is similar, but more complete in some way.

http://paste.pocoo.org/show/222332/

Main differences:

  • provide the iterator interface to yield the page numbers like 1 .... 19 20 21 22 23 24 25 .... 86
  • provide links for the pages (url_for)
  • use conventional names "has_next" "has_previous" (instead of "have_previous")
    (in the spirit of "hasattr" and "dict.has_key")

VersionedMeta example in docs

I tried the VersionedMeta example in the docs and it doesn't work.
Using: SQLAlchemy 0.6.8; Flask-SQLAlchemy 0.15
history_meta.py is the unchanged version from SQLAlchemy 0.6.8 examples.

Code:

from flask import Flask
from flaskext.sqlalchemy import SQLAlchemy
from history_meta import VersionedMeta, VersionedListener

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
db = SQLAlchemy(app, session_extensions=[VersionedListener()])

class User(db.Model):
    __metaclass__ = VersionedMeta
    username = db.Column(db.String(80), unique=True)
    pw_hash = db.Column(db.String(80))

if __name__ == '__main__':
    app.run()

Error:

Traceback (most recent call last):
  File "flask_sqla_versiontest.py", line 13, in <module>
    class User(db.Model):
TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

What is wrong?

how to let flask-sqlalchemy's query object select columns ( or say fields )?

hi, Armin,

I met some problem that wired me the whole day. I'm using flask/flask-sqlalchemy/postgresql, and I want to do this:

published_sites = msg_published.query
.filter( and_(*filter_clause) )
.group_by( msg_published.site_id )
.order_by( order_clause )
.paginate( page_no, per_page, error_out = False )
but in mysql, it is OK, and in postgresql it is wrong and ask for the other fields besides site_id either in a group by clause or in a aggregation function, I know that postgresql is stricter on SQL than mysql , so I must select the site_id in the query object of msg_published, but in pure sqlalchemy I can do like this:

published_sites = session.query( msg_published.site_id )
.filter( and_(*filter_clause) )
.group_by( msg_published.site_id )
.order_by( order_clause )
.paginate( page_no, per_page, error_out = False )
and in flask-sqlalchemy, how to get it work?

apply_driver_hacks: dialect+driver URI syntax fails

(sqlalchemy.py)
def apply_driver_hacks(self, app, info, options):
if info.drivername == 'mysql':

This fails to recognize URIs like 'mysql+pymsql://...'
I guess it should check 'contains mysql' or even a regex check like '^mysql+'.

Thanks.

use of partial() in create_scoped_session prevents SQLAlchemy.session from being used with SQL Alchemy event listeners

SQL Alchemy events are registered by calling the listen function with a class, an event name and a function. By returning a partial, you make it difficult to attach listeners. I suppose you could work around this issue by calling type(db.session()), however a decent amount of debugging is required to figure out why things don't work in the first place.

A simple solution is to create a singalling_session_maker function that takes the same arguments as signalling_session, then define _SignallingSession inside this function with a reduced init function, and return it. Then you can just call that factory inside of scoped_session().

init_app doesn't assign arg to app attr

Perhaps I'm misunderstanding the intended use of SQLAlchemy.init_app, but it appears that it doesn't assign it's arg (a Flask application object) to its instance.

This tripped me up as I was creating my SQLALchemy instance in a separate module from my application and tests and binding it to the Flask application object later. I had thought from the documentation that this meant I should use the init_app method, but doing so just threw errors that the SQLAlchemy instance wasn't bound to an application object.

Manually assigning the application object to the SQLAlchemy.app attribute works around the problem.

Support for before_flush and after_flush signals

When I have a model like this:

class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, nullable=False, unique=True)
    count = db.Column(db.Integer, nullable=False, default=0)

class Article(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    content = db.Column(db.Text, nullable=False)
    category = db.relationship('Category', backref='articles')

and want to update count on Category for every new Article, I would do:

from sqlalchemy.orm.attributes import get_history

def update_category_count(sender, changes):
    for model, change in changes:
        if isinstance(model, Article):
            if change == 'new':
                model.category.count += 1
            elif change == 'deleted':
                model.category.count -= 1
            elif change == 'updated':
                # Need to know old category before updating `Category.count`.
                added, unchanged, deleted = get_history(model, 'category')
                if added and deleted:
                    deleted[0].count -= 1
                    added[0].count += 1
    db.session.commit()

models_committed.connect(update_category_count)

This won't going to work for several reason:

  1. The session is no longer active at this point. Calling db.session.commit() here will raise InvalidRequestError.
  2. get_history is not able to retrieve older state, presumably because the model is already committed and object no longer being marked as dirty.
  3. Altering model.category.count won't issue an UPDATE for some reason. From my understanding, it is not possible to modify flush plan at this point.

No changes are sent to update_category_count when changing to before_models_committed. update_category_count need to be called by before_flush in order to modify flush plan:

from flask.signals import Namespace
from sqlalchemy.orm.interfaces import SessionExtension, EXT_CONTINUE

signals = Namespace()
before_flush = signals.signal('models-before-flush')

class FlushSignalExtension(SessionExtension):
    def before_flush(self, session, flush_context, instances):
        before_flush.send(session.app, session=session, instances=instances)
        return EXT_CONTINUE

from itertools import ifilter
from sqlalchemy.orm.attributes import get_history

def update_category_count(sender, session, instances):
    predicate = lambda s: isinstance(s, Article)
    for article in ifilter(predicate, session.new):
        article.category.count += 1
    for article in ifilter(predicate, session.deleted):
        article.category.count -= 1
    for article in ifilter(predicate, session.dirty):
        added, unchanged, deleted = get_history(article, 'category')
        if added and deleted:
            deleted[0].count -= 1
            added[0].count += 1

before_flush.connect(update_category_count)

This works, category is properly UPDATEd. So I think it would be useful if Flask has before_flush and after_flush signals built-in.

(I have not tested the code above, but they're reproduced from an actual case of a production code I'm not allowed to post part of it anywhere. Sorry.)

Bcrypt data being changed on insert into SQLite

I have an implementation of Mozilla's password policy in Python that creates an HMAC key, uses b64 encoded version of it within bcrypt to create an encrypted password.

When I create one of these manually and insert it in to SQLite directly, it all works fine and is as expected.

When I insert this in to the database using a model and db.session the value in SQLite is not the value that was inserted.

i.e.

db.session.add(User("kura", "bcrypt$2a$12$7kmx7ZdtXwUSsfdfBxp/ouhGnWhPIylCZUYhifnIaMcyM4hkNg9Jq$2012-02-14", "[email protected]", "Kura"))
db.session.commit()

When I query that result, instead of getting the value I inserted I get

bcrypt$2a$12$RGkcKVIM6.Crv.ZIzVn5EuxN6OYEHic2zO8IBhCHVev0WT7F0klKu$2012-02-14

Querying SQLite directly using the Linux binary shows that the second (incorrect) value is the one stored.

If I change that value manually using the SQLite binary and then requery from Python it is correct.

Any ideas why this would be the case?

A commit_on_success decorator

Since most of the projects using sqlalchemy uses mysql / postgres there is a good chance of using transactions. Having a commit_on_success decorator can save a try except block in the view functions. Here is a rough draft of the decorator I wrote.

https://gist.github.com/14d12595f3dfa307a354

Just wondering if its a good idea to get the db object from the function object. (line # 11)?

Adopt CHANGES and setup.cfg

Flask-SQLAlchemy is big enough that it should get a CHANGES and setup.cfg file for improved release management.

The "reflect" method raises TypeError exception.

Flask-sqlalchemy version: 0.15
SQLAlchemy version: 0.7.3

Problem:

    db = SQLAlchemy()
    db.init_app(myapp)
    db.reflect(app=myapp)
File "/home/user/Envs/myenv/lib/python2.7/site-packages/flaskext/sqlalchemy.py", line 811, in reflect
    self._execute_for_all_tables(app, bind, 'reflect')
  File "/home/user/Envs/myenv/lib/python2.7/site-packages/flaskext/sqlalchemy.py", line 787, in _execute_for_all_tables
    op(bind=self.get_engine(app, bind), tables=tables)
    TypeError: reflect() got an unexpected keyword argument 'tables'

It seems like the _execute_for_all_tables method is not suitable for the reflect method.

Replace db.Query with BaseQuery

I just subclassed db.Query and was surprised that my custom query property didn't have get_or_404().

I wonder if db.Query should really refer to the flaskext.sqlalchemy.BaseQuery class. I realize that this is not without it's problems, since that would essentially be breaking the promise that you can access the SQLAlchemy identifiers via db.*, and Query would be the lone exception; but it seems to be that use-case wise, it's much more common that people really want to subclass BaseQuery; it should be rare that soneone would insist on working with the plain SQLAlchemy Query class.

Allow specifying a different Model as a base

Right now, there's no simple way to provide a base Model object because everything is done on the make_declarative_base function, the options is to override and redo what's done on that function. Could we provide a different Model when creating the SQLAlchemy object? or provide the model as a class attribute(since I'm already subclassing it)?

Proper model directory structure

I found no mention in the docs about the proper way to structure models in a Flask app. Right now I have this:

# app.py
db = SQLAlchemy(app)

and:

# models.py
from app import db
class MyModel(db.Model):
# ...

But this means I have a circular dependency once I try to do:

# app.py
from models import MyModel

It's worth mentioning how this should be done in the docs.

Broken support of __abstract__ mark

class User(db.Model):
    __abstract__ = True
    id = Column(Integer, primary_key=True)

class Manager(User):
    name = Column(String)

This code must declare only one table manager, with two fields id and name. But Flask-SQLAlchemy doesn't generate __tablename__ for class Manager, because it doesn't have a primary key field. So, accessing Manager.__tablename__ results in user, which obviously not what I want.

No query in db.Model subclasses

Hello,

I'm trying to complete the sample application as described on http://packages.python.org/Flask-SQLAlchemy/ . I'm trying to query the users I created as described in the code section after "And how do you get the data back? Easy as pie:" and here is what I get:

(veFlask)remy@remy-virtual-machine:~/Projects/Hello World$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from dbtest import User
>>> users = User.query.all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'all'
>>> print User.query
None

I've followed the previous sample application steps to the point. I'm using Flask 0.6 and Flask-SQLAlchemy 0.9.1.

Support for multiple databases

We have master and slave replication for our database and just want the ability to read from the database of our choice. Will Flask-SQLAlchmey support for multiple databases? If not any work arounds?

Would be awesome to have query abilities like django

User.query.filter_by(id=1).using("slave")

SQLAlchemy.init_app() doesn't work

I try to bind the application after my model declaration to the SQLAlchemy object with the function db.init_app(app), but the db engine is always None.

info parameter discarded on _make_table

The documentation mentions adding an info={'bind_key': 'users'} parameter to a Table to bind it. However, this parameter is thrown away:

def _make_table(db):
    def _make_table(*args, **kwargs):
        if len(args) > 1 and isinstance(args[1], db.Column):
            args = (args[0], db.metadata) + args[1:]
        info = kwargs.pop('info', None) or {}
        info.setdefault('bind_key', None)
        return sqlalchemy.Table(*args, **kwargs)
    return _make_table

info above is never re-added to kwargs. A simple fix:

def _make_table(db):
    def _make_table(*args, **kwargs):
        if len(args) > 1 and isinstance(args[1], db.Column):
            args = (args[0], db.metadata) + args[1:]
        info = kwargs.pop('info', None) or {}
        info.setdefault('bind_key', None)
        kwargs['info'] = info
        return sqlalchemy.Table(*args, **kwargs)
    return _make_table

For applications needing to use this functionality now, a workaround is to set the info attribute right after you create the object.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.