【发布时间】:2013-01-19 01:42:33
【问题描述】:
貌似Beaker支持两个数据库后端,ext:database和ext:sqla,但是它们有什么区别呢?
【问题讨论】:
貌似Beaker支持两个数据库后端,ext:database和ext:sqla,但是它们有什么区别呢?
【问题讨论】:
看源码(Beaker-1.6.4-py2.7.egg),后端初始化不同,数据库schema略有不同。
关键区别似乎在于您是要使用预先存在的 SQLAlchemy 连接 (ext:sqla) 还是创建全新的连接 (ext:database)。
另外,ext:database 可以完全在 ini 配置文件中配置,而 ext:sqla 不能。
在配置文件中,ext:database 至少需要定义session.url 指向数据库。您可以指定 session.table_name 指向表(如果您使用了默认 beaker_cache 以外的其他内容)以及 session.schema_name 如果您想玩弄额外的设置。最后,session.sa_opts 可以使用 SQLAlchemy 引擎的选项字典指定。
ext:sqla 只需要一个绑定对象(SQLAlchemy Engine 或 Connection 对象)和一个绑定的 SQLAlchemy Table 对象。在调用 Pyramid 的配置器时动态设置这些值很容易。由于配置文件只能接受字符串,所以在ini配置文件中不能设置ext:sqla字段。
表架构也略有不同。 ext:database 架构后跟 ext:sqla 架构:
cache = sa.Table(table_name, meta,
sa.Column('id', types.Integer, primary_key=True),
sa.Column('namespace', types.String(255), nullable=False),
sa.Column('accessed', types.DateTime, nullable=False),
sa.Column('created', types.DateTime, nullable=False),
sa.Column('data', types.PickleType, nullable=False),
sa.UniqueConstraint('namespace'),
schema=schema_name if schema_name else meta.schema
)
sa.Table(table_name, metadata,
sa.Column('namespace', sa.String(255), primary_key=True),
sa.Column('accessed', sa.DateTime, nullable=False),
sa.Column('created', sa.DateTime, nullable=False),
sa.Column('data', sa.PickleType, nullable=False),
schema=schema_name if schema_name else metadata.schema)
ext:database 模式如果按原样使用会出错,因为 id 需要有一个默认值。在 Postgres 中,只需将类型创建为 Serial 而不是 Integer 即可自动生成默认值。
ext:sqla 是 ext:database 模式的完整子集,即使主键不同。 ext:sqla 的 PK 是命名空间,但由于 ext:database 的架构使命名空间 UNIQUE 而非 NULL,因此满足将其视为主键的所有要求。如果希望在 ext:sqla 和 ext:database 之间进行更改,则始终实现 ext:database 模式是有意义的。 ext:sqla 通过对数据列使用 SQLAlchemy PickleType 来使用自动酸洗。手动在后端创建表,而不是让 ext:sqla 创建它,似乎可以防止这种自动酸洗发生。
将这样的东西放入配置文件中:
sqlalchemy.url = postgresql://user@host.com/particulardb
...
session.type = ext:database
session.url = postgresql://user@host.com/particulardb
即使 ext:database session.url 和 sqlalchemy.url 是同一个数据库,也会从 Pyramid 实例建立两个连接。
ext:sqla 将纠正两个连接的创建;一旦 sqlalchemy.url 绑定到 SQLAlchemy 引擎,ext:sqla 就可以使用该引擎,而不是创建新连接。
我认为这是一个足够常见的用例(ext:sqla SQLAlchemy Engine = pyramid SQLAlchemy Engine),可以在静态配置文件中进行特殊处理。如果有这种特殊处理,我没找到。
【讨论】: