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

时间:2010-04-21 19:19:31

标签: sqlite postgresql schema sqlalchemy pylons

我有一个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'))

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

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

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

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

3 个答案:

答案 0 :(得分:9)

  

我想继续使用SQLite   开发和测试。

     

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

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

停止它。停下来吧。

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

安装PostgreSQL。

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

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

严重。

答案 1 :(得分:2)

我自己只是一个初学者,我没有使用过Pylons,但是......

我注意到您正在将表和关联的类组合在一起。如果你将它们分开怎么样?

import sqlalchemy as sa
meta = sa.MetaData('sqlite:///tutorial.sqlite')
schema = None
hockey_table = sa.Table('hockey', meta,
                      sa.Column('score_id', sa.types.Integer, sa.Sequence('score_id_seq', optional=True), primary_key=True),
                      sa.Column('baseball_id', sa.types.Integer, sa.ForeignKey('summer.baseball.baseball_id')),
                      schema = schema,
                    )

meta.create_all()

然后你可以创建一个单独的

class Hockey(Object):
    ...

mapper(Hockey, hockey_table)

如果您正在使用sqlite,那么只需在上面设置schema = None无处理,否则你想要的值。

你没有一个有效的例子,所以上面的例子也不是一个有效的例子。然而,正如其他人所指出的那样,尝试保持跨数据库的可移植性最终是一场失败的游戏。我会向人们添加一个+1,建议你到处都使用PostgreSQL。

HTH,问候。

答案 2 :(得分:0)

我不确定这是否适用于外键,但是有人可以尝试使用SQLAlchemy的Multi-Tenancy Schema Translation for Table objects。它对我有用,但是我将自定义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)

...

这是create_engine的文档。有另一本question可能与此相关。

但是可能会有冲突的表名,所有架构名称都映射到None