Beaker中数据库和sqla后端的区别?
看起来 Beaker 支持两种数据库后端,分别是 ext:database 和 ext:sqla,但它们之间有什么区别呢?
1 个回答
概述
看一下源代码(Beaker-1.6.4-py2.7.egg),可以发现后端初始化和数据库结构有些不同。
主要的区别在于你是想使用一个已经存在的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引擎或连接对象)和一个绑定的SQLAlchemy表对象。在调用Pyramid的Configurator时,动态设置这些值是很简单的。由于配置文件只能接受字符串,所以ext:sqla的字段不能在ini配置文件中设置。
详细信息:表结构
表结构也有些许不同。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的主键是namespace,但由于ext:database的结构将namespace设置为唯一且不能为空,因此满足了将其视为主键的所有要求。如果将来想在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引擎 = pyramid的SQLAlchemy引擎),应该在静态配置文件中有特别的处理。如果有这样的特别处理,我还没有找到。