Flask的SQLAlchemy

很多人更喜欢 SQLAlchemy 用于数据库访问。在这种情况下,我们建议您在烧瓶应用程序中使用包而不是模块,并将模型放入单独的模块中。 (大型应用程序包 )虽然这不是必要的,但它很有意义。

使用SQLAlchemy有四种非常常见的方法。我将在这里概述它们:

Flask-SQLAlchemy扩展

因为sqlAlchemy是一个常见的数据库抽象层和对象关系映射器,需要一些配置工作,所以有一个flask扩展可以为您处理这个问题。如果您想快速入门,建议这样做。

你可以下载 Flask-SQLAlchemyPyPI .

声明的

SQLAlchemy中的声明性扩展是使用SQLAlchemy的最新方法。它允许您一次性定义表和模型,类似于Django的工作方式。除了以下文本外,我还建议 declarative 延伸。

举个例子 database.py 应用程序模块:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, declarative_base

engine = create_engine('sqlite:////tmp/test.db')
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    # import all modules here that might define models so that
    # they will be registered properly on the metadata.  Otherwise
    # you will have to import them first before calling init_db()
    import yourapplication.models
    Base.metadata.create_all(bind=engine)

要定义模型,只需子类化上面代码创建的“Base”类。如果您想知道为什么我们不需要关心这里的线程(就像我们在上面使用:data: ' ~flask的SQLite3示例中所做的那样)。对象):这是因为SQLAlchemy已经用:class: ' ~ SQLAlchemy .orm.scoped_session '为我们做了这一点。

要在应用程序中以声明性的方式使用SQLAlchemy,只需将以下代码放入应用程序模块。flask将在请求结束或应用程序关闭时自动删除数据库会话::

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

下面是一个示例模型(将其放入 models.py ,例如::

from sqlalchemy import Column, Integer, String
from yourapplication.database import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return f'<User {self.name!r}>'

要创建数据库,可以使用 init_db 功能:

>>> from yourapplication.database import init_db
>>> init_db()

您可以像这样将条目插入数据库:

>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()

查询也很简单:

>>> User.query.all()
[<User 'admin'>]
>>> User.query.filter(User.name == 'admin').first()
<User 'admin'>

手动对象关系映射

与上面的声明性方法相比,手动对象关系映射有一些优点和缺点。主要的区别在于,您分别定义表和类,并将它们映射在一起。它更灵活,但更适合打字。一般来说,它的工作方式类似于声明性方法,因此请确保也将应用程序拆分为包中的多个模块。

下面是一个例子 database.py 应用程序模块:

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker

engine = create_engine('sqlite:////tmp/test.db')
metadata = MetaData()
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
def init_db():
    metadata.create_all(bind=engine)

与声明性方法一样,您需要在每个请求或应用程序上下文关闭之后关闭会话。将其放入应用程序模块:

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

下面是一个示例表和模型(将其放入 models.py ):

from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.orm import mapper
from yourapplication.database import metadata, db_session

class User(object):
    query = db_session.query_property()

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return f'<User {self.name!r}>'

users = Table('users', metadata,
    Column('id', Integer, primary_key=True),
    Column('name', String(50), unique=True),
    Column('email', String(120), unique=True)
)
mapper(User, users)

查询和插入的工作方式与上面的示例完全相同。

SQL抽象层

如果只想使用数据库系统(和SQL)抽象层,那么基本上只需要引擎:

from sqlalchemy import create_engine, MetaData, Table

engine = create_engine('sqlite:////tmp/test.db')
metadata = MetaData(bind=engine)

然后,您可以像上面的示例一样在代码中声明这些表,或者自动加载它们:

from sqlalchemy import Table

users = Table('users', metadata, autoload=True)

要插入数据,可以使用 insert 方法。我们必须先建立连接,这样才能使用事务:

>>> con = engine.connect()
>>> con.execute(users.insert(), name='admin', email='admin@localhost')

SQLAlchemy将自动为我们提交。

要查询数据库,请直接使用引擎或使用连接:

>>> users.select(users.c.id == 1).execute().first()
(1, 'admin', 'admin@localhost')

这些结果也是类似dict的元组:

>>> r = users.select(users.c.id == 1).execute().first()
>>> r['name']
'admin'

还可以将SQL语句的字符串传递给 execute() 方法:

>>> engine.execute('select * from users where id = :1', [1]).first()
(1, 'admin', 'admin@localhost')

有关SQLAlchemy的更多信息,请访问 website .