使用SQLAlchemy,SQLite和Postgresql的模式限定表?

Chr*_*eid 8 sqlite postgresql schema pylons sqlalchemy

我有一个Pylons项目和一个实现模式限定表的SQLAlchemy模型:

class Hockey(Base):
    __tablename__ = "hockey"
    __table_args__ = {'schema':'winter'}
    hockey_id = sa.Column(sa.types.Integer, sa.Sequence('score_id_seq', optional=True), primary_key=True)
    baseball_id = sa.Column(sa.types.Integer, sa.ForeignKey('summer.baseball.baseball_id'))
Run Code Online (Sandbox Code Playgroud)

这段代码适用于Postgresql,但在表和外键名称上使用SQLite时失败(由于SQLite缺乏架构支持)

sqlalchemy.exc.OperationalError:(OperationalError)未知数据库"winter"'PRAGMA"winter".table_info("hockey")'()

我想继续使用SQLite进行开发和测试.

有没有办法在SQLite上优雅地失败?

Mik*_*ll' 9

我想继续使用SQLite进行开发和测试.

有没有办法在SQLite上优雅地失败?

很难知道从哪个问题开始.所以...

停下来.停下来吧

有些开发人员无法在目标平台上进行开发.他们的生活是艰难的 - 从一个环境到另一个环境的移动代码(有时是编译器),调试两次(有时必须在目标平台上远程调试),逐渐意识到咀嚼他们的直觉实际上是开始溃疡.

安装PostgreSQL.

当您可以使用相同的数据库环境进行开发,测试和部署时,您应该这样做.

更不用说QA团队了.他们为什么要测试他们不会发货的东西呢?如果您在PostgreSQL上部署,请确保您在PostgreSQL上的工作质量.

认真.

  • 这个问题的很大一部分是单元测试,为每个测试创建一个干净的数据库对于 postgres 来说并不是一个真正可行的解决方案。也许这就是人们寻求答案而欲罢不能的原因之一。 (2认同)

P. *_* B. 8

我不确定这是否适用于外键,但有人可以尝试使用 SQLAlchemy 的多租户架构转换表对象。它对我有用,但我将自定义primaryjoinsecondaryjoin表达式与复合主键结合使用。

模式转换映射可以直接传递给引擎创建者:

...

if dialect == "sqlite":
    url = lambda: "sqlite:///:memory:"
    execution_options={"schema_translate_map": {"winter": None, "summer": None}}
else:
    url = lambda: f"postgresql://{user}:{pass}@{host}:{port}/{name}"
    execution_options=None

engine = create_engine(url(), execution_options=execution_options)

...
Run Code Online (Sandbox Code Playgroud)

这是create_engine的文档。还有一个关于 so 的问题可能与这方面相关。

但是,所有模式名称都映射到的表名称可能会发生冲突None


Riq*_*iqq 7

我知道这是一个 10 多年的老问题,但我最近遇到了同样的问题:生产中的 Postgres 和开发中的 sqlite。

解决方案是在引擎调用“connect”方法时注册一个事件侦听器。

@sqlalchemy.event.listens_for(engine, "connect")
def connect(dbapi_connection, connection_record):
    dbapi_connection.execute('ATTACH "your_data_base_name.db" AS "schema_name"')
Run Code Online (Sandbox Code Playgroud)

仅使用一次 ATTACH 语句是行不通的,因为它只影响单个连接。这就是为什么我们需要事件侦听器来对所有连接执行 ATTACH 语句。