【问题标题】:Can related sequence name be extracted from SQLAlchemy model's column?可以从 SQLAlchemy 模型的列中提取相关的序列名称吗?
【发布时间】:2018-09-24 18:16:08
【问题描述】:

我们以简单的 SQLAlchemy 模型为例:

class Organization(Base):
    __tablename__ = 'organization'

    id = Column(Integer, primary_key=True)
    # ... and so on...

在这种情况下,当在 PostgreSQL 上时,由于 id 是主键,因此该模型将创建一个名为 organization_id_seq 的序列器。

是否有可能以某种方式从该定序器为 (Organization.id) 或Organization 类本身创建的字段中提取此自动生成的定序器名称(或其他定序器详细信息)?或者也许唯一的方法是“手动”在数据库中检查它?

动机不是在音序器重置实用程序中硬编码音序器名称,我们在某些测试中使用的团队。

【问题讨论】:

  • 自动创建的主键序列总是由表名、列名和seq后缀组成,下划线分隔。
  • 谢谢,这会让事情变得简单。无论 Postgres 版本如何,人们都认为这是理所当然的事情,还是只是一些可能会发生变化的实现细节?
  • 嗯,我与 Postges 合作多年,一直都是这样。我看不出有人想改变它的任何理由。但另一方面,据我所知,它没有正式记录
  • 很高兴知道。谢谢。

标签: python postgresql orm sqlalchemy


【解决方案1】:

以这种方式找到:初始化元数据,反映特定表而不是遍历所有约束并找到您需要的一个。

from model import Model
from sqlalchemy import MetaData
m = MetaData()
m.reflect(Model.query.session.bind, only=[Model.__tablename__])
table_constraints = m.tables[Model.__tablename__].constraints
for constr in table_constraints:
    # checking isinstance(constr, PrimaryKeyConstraint) can be added
    for col in c.columns.values():
        if col.server_default is not None and col.server_default.arg is not None:
            print c.server_default.arg
            # prints nextval('table_id_seq'::regclass)

UPD。 版本允许在不迭代的情况下获取特定列的序列名称:

from model import Model
from sqlalchemy import MetaData
m = MetaData()
m.reflect(Model.query.session.bind, only=[Model.__tablename__])
sequence_name = Model.id.server_default.arg.text

【讨论】:

  • 这可能是一个很好的方向。不过,在我的情况下,col.server_default 是 None,但我只做了一个简短的检查。我会深入研究它并尝试让它明天工作。
  • 如果你没有在列定义中指定它可能是默认的。 Metadata().reflect() 从 DBMS 中检索 DDL:全表结构、索引、约束、触发器等。如果您只为 postgresql 表的列指定 primary_key=True,sqla 会为其生成 serial 类型。在它之后,Postgresql 为其分配了一些序列。
  • 你是对的,我昨天尝试的元数据没有正确反映。它正在工作。但是,我认为获得此最终文本nextval('table_id_seq'::regclass) 的更简单且更优雅的方式(无需遍历所有表的约束)是m.tables[Model.__tablename__].columns['id'].server_default.arg.text。如果您发现对代码进行了适当的修改,我认为您可以更新答案,我会接受。感谢您的努力!
  • 您说得对,但仅针对您的情况。我的版本更宽。无论如何更新:)
猜你喜欢
  • 2016-10-31
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
相关资源
最近更新 更多