使用 SQLAlchemy

    有四种 SQLAlchemy 的常用方法,下面一一道来:

    因为 SQLAlchemy 是一个常用的数据库抽象层,并且需要一定的配置才能使用,因此 我们为你做了一个处理 SQLAlchemy 的扩展。如果你需要快速的开始使用 SQLAlchemy ,那么推荐你使用这个扩展。

    你可以从 PyPI 下载 。

    SQLAlchemy 中的声明扩展是使用 SQLAlchemy 的最新方法,它允许你像 Django 一 样,在一个地方定义表和模型然后到处使用。除了以下内容,我建议你阅读 声明 的官方文档。

    以下是示例 模块:

    要定义模型的话,只要继承上面创建的 Base 类就可以了。你可能会奇怪这里为什 么不用理会线程(就像我们在 SQLite3 的例子中一样使用 对象)。 原因是 SQLAlchemy 已经用 scoped_session 为我们做 好了此类工作。

    如果要在应用中以声明方式使用 SQLAlchemy ,那么只要把下列代码加入应用模块就 可以了。 Flask 会自动在请求结束时或者应用关闭时删除数据库会话:

    1. from yourapplication.database import db_session
    2. @app.teardown_appcontext
    3. def shutdown_session(exception=None):
    4. db_session.remove()
    1. from sqlalchemy import Column, Integer, String
    2. from yourapplication.database import Base
    3. class User(Base):
    4. __tablename__ = 'users'
    5. id = Column(Integer, primary_key=True)
    6. name = Column(String(50), unique=True)
    7. email = Column(String(120), unique=True)
    8. def __init__(self, name=None, email=None):
    9. self.name = name
    10. self.email = email
    11. def __repr__(self):
    12. return f'<User {self.name!r}>'

    可以使用 init_db 函数来创建数据库:

    1. >>> from yourapplication.database import init_db

    在数据库中插入条目示例:

    1. >>> from yourapplication.database import db_session
    2. >>> from yourapplication.models import User
    3. >>> db_session.add(u)
    4. >>> db_session.commit()

    查询很简单:

    人工对象关系映射相较于上面的声明方式有优点也有缺点。主要区别是人工对象关系 映射分别定义表和类并映射它们。这种方式更灵活,但是要多些代码。通常,这种方 式与声明方式一样运行,因此请确保把你的应用在包中分为多个模块。

    示例 database.py 模块:

    1. from sqlalchemy import create_engine, MetaData
    2. from sqlalchemy.orm import scoped_session, sessionmaker
    3. engine = create_engine('sqlite:////tmp/test.db')
    4. metadata = MetaData()
    5. db_session = scoped_session(sessionmaker(autocommit=False,
    6. autoflush=False,
    7. bind=engine))
    8. def init_db():
    9. metadata.create_all(bind=engine)

    就像声明方法一样,你需要在每个请求结束后或者应用情境关闭后关闭会话。把以下 代码放入你的应用模块:

    1. from yourapplication.database import db_session
    2. @app.teardown_appcontext
    3. def shutdown_session(exception=None):
    4. db_session.remove()

    以下是一个示例表和模型(放入 models.py 中):

    1. from sqlalchemy import Table, Column, Integer, String
    2. from sqlalchemy.orm import mapper
    3. from yourapplication.database import metadata, db_session
    4. class User(object):
    5. self.name = name
    6. self.email = email
    7. def __repr__(self):
    8. return f'<User {self.name!r}>'
    9. users = Table('users', metadata,
    10. Column('id', Integer, primary_key=True),
    11. Column('name', String(50), unique=True),
    12. Column('email', String(120), unique=True)
    13. )
    14. mapper(User, users)

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

    1. from sqlalchemy import create_engine, MetaData, Table
    2. engine = create_engine('sqlite:////tmp/test.db')
    3. metadata = MetaData(bind=engine)

    然后你要么像前文中一样在代码中声明表,要么自动载入它们:

    可以使用 insert 方法插入数据。为了使用事务,我们必须先得到一个连接:

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

    SQLAlchemy 会自动提交。

    可以直接使用引擎或连接来查询数据库:

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

    查询结果也是类字典元组:

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

    你也可以把 SQL 语句作为字符串传递给 execute() 方法:

    1. (1, 'admin', u'admin@localhost')