【问题标题】:SQL Alchemy Composite Key OrderSQLAlchemy 复合键顺序
【发布时间】:2019-05-03 06:25:58
【问题描述】:

我想创建一个 (date,id) 形式的复合主键。我的代码目前看起来有点像这样

class Gyroinfo(Base):
    __tablename__ = 'GYROINFO'

    id = Column(Integer, primary_key=True,autoincrement = True)
    date = Column(DateTime, primary_key = True)

但这默认为 (id, date) 形式的主键。如何切换主键顺序?

【问题讨论】:

  • 在 id 工作之前初始化日期。我不明白为什么订单会有所不同
  • 在 id 之前初始化日期似乎不起作用。
  • 你能给我们举个例子说明为什么顺序很重要吗?这是一个约束,所以顺序没有任何区别。
  • 我想在表格上放一个 (date,id) 形式的索引,所以如果我可以将主键设置为 (date,id) 形式,我们就不必声明任何额外的索引。
  • 您使用的是什么数据库?我刚刚对sqlite 进行了快速测试,更改列的定义顺序确实改变了在发出的 sql 中指定列的顺序。例如。 id/日期:CREATE TABLE "GYROINFO" (id INTEGER NOT NULL, date DATETIME NOT NULL, PRIMARY KEY (id, date)) 和日期/id:CREATE TABLE "GYROINFO" (date DATETIME NOT NULL, id INTEGER NOT NULL, PRIMARY KEY (date, id))

标签: python sqlalchemy


【解决方案1】:

我假设你在这里使用 MySQL,所以如果不让我知道,我会删除这个答案。

您可以阅读 Mike Bayer 所说的关于使用 MySQL here 重新排序主键字段的内容。以及为什么SQLAlchemy 会出现这样的行为背后的原因here

您可以通过在id 字段上使用PrimaryKeyConstraint 和单独的UniqueConstraint 来实现您想要的。例如:

class Gyroinfo(Base):
    __tablename__ = 'GYROINFO'

    id = Column(Integer, autoincrement=True, unique=True)
    date = Column(DateTime)

    __table_args__ = (
        PrimaryKeyConstraint(date, id),
    )

这会产生以下 sql:

CREATE TABLE `GYROINFO` (
        id INTEGER NOT NULL AUTO_INCREMENT,
        date DATETIME NOT NULL,
        PRIMARY KEY (date, id),
        UNIQUE (id)
)

如果id 字段定义中没有额外的unique=True,SQLAlchemy 会发出一个CREATE TABLE,其中的列按您希望的顺序排列:

CREATE TABLE `GYROINFO` (
        id INTEGER NOT NULL AUTO_INCREMENT,
        date DATETIME NOT NULL,
        PRIMARY KEY (date, id)
)

但是被MySQL拒绝了:

Incorrect table definition; there can be only one auto column and it must be defined as a key

但是,它引出了一个问题,即为什么您需要在主键中使用 date 字段。由于id 是自动递增的,它在表中的所有条目中都是唯一的,因此在带有id 的复合字段中包含date 不会增加额外的复杂性。我会坚持:

class Gyroinfo(Base):
    __tablename__ = 'GYROINFO'

    id = Column(Integer, autoincrement=True, primary_key=True)
    date = Column(DateTime, index=True)

【讨论】:

  • 谢谢!我们实际上使用的是 PostgreSQL,它接受 SQLAlchemy 命令。至于为什么我们希望在主字段中包含日期 - 我们正在使用时间序列扩展 (timescaledb),它要求表的主键包含日期。
  • 有道理。很高兴我能帮上忙。
  • 此策略不适用于PostgreSQL... 无法确定主键索引的顺序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-03
  • 2014-06-16
  • 2021-04-24
  • 2010-11-22
  • 2015-02-02
  • 1970-01-01
  • 2011-11-22
相关资源
最近更新 更多