【问题标题】:create column not primary key but identity on sqlalchemy for sql server在 sqlalchemy for sql server 上创建列不是主键而是标识
【发布时间】:2020-12-16 02:18:13
【问题描述】:

我已创建此代码以在 sql server 上创建具有标识的列,但此列不是主键。

我需要有name 作为主键和id 作为标识列,但不是主键。问题是我不知道如何使用 sqlalchemy 来做到这一点。我试图将 auto_increment 放在“id”上,但它不起作用。

def change_pk(table, sql_table_name, list_pk_column):
    str_pk_column = ""
    for item in list_pk_column:
        str_pk_column += item + ","
    str_pk_column = str_pk_column[:-1]
    event.listen(
        table,
        "after_create",
        DDL(
            """ALTER TABLE {0} DROP CONSTRAINT {0}_id;
                 ALTER TABLE {0} ADD CONSTRAINT {0}_un_id UNIQUE (id);
                 ALTER TABLE {0} ADD CONSTRAINT {0}_pk PRIMARY KEY ({1})""".format(
                sql_table_name, str_pk_column
            )
        ),
    )


msg_users = sa.Table(
    "Msg_Users",
    metadata,
    sa.Column("id", sa.Integer, info={}),
    sa.Column("name", sa.Unicode(50), nullable=False, info={}),
    sa.Column("mobile", sa.Unicode(15), info={}),
    sa.Column("email", sa.Unicode(80), info={}),
    sa.Column(
        "last_update",
        sa.DateTime,
        server_default=sa.func.current_timestamp(),
        server_onupdate=sa.func.current_timestamp(),
        info={},
    ),
    sa.PrimaryKeyConstraint("id", name="Msg_Users_id"),
    info={},
    autoload=aload,
)

change_pk(msg_users, "Msg_Users", ["name"])

有没有更简单的方法?

【问题讨论】:

  • 我不关注他们的问题,仅使用sa.PrimaryKeyConstraint('id')生成的主键有什么问题?
  • 可能有误会。我将尝试以更好的方式解释我的问题。我需要将“name”作为主键,将“id”作为标识列(它不是主键)。问题是我不知道如何使用 sqlalchemy 来做到这一点。我试图将 auto_increment 放在“id”上,但它不起作用。
  • 请通过帖子编辑而非 cmets 进行澄清。

标签: python sqlalchemy primary-key identity


【解决方案1】:

您可以创建自己的用户定义类型来实现这一点。

class IdentityType(types.UserDefinedType):
    def get_col_spec(self):
        return 'INT Identity(1,1)'

    def bind_processor(self, dialect):
        def process(value):
            if value is not None:
                if isinstance(value, int):
                    return value
                else:
                    return int(value)
            else:
                return None
        return process

    def result_processor(self, dialect, coltype):
        def process(value):
            if value is not None:
                int(value)
            return value
        return process

【讨论】:

    【解决方案2】:

    查看方言代码并检查documentationthis 似乎是不可能的。

    你可以试试这个:

    from sqlalchemy import Table, Integer, Sequence, Column, Unicode
    
    Table('test', metadata,
        Column('id', Integer, Sequence('some_sequence')),
        Column('name', Unicode(80), primary_key=True)).create(some_engine)
    

    但从文档中它不应该工作:

    SQL Server 使用 IDENTITY 构造,可以放在整数主键上。 SQLAlchemy 在其默认的“自动增量”中考虑 IDENTITY 行为,在 Column.autoincrement 中描述;这意味着通过 默认情况下,表中的第一个整数主键列将是 被认为是标识列,并将生成 DDL:

    http://docs.sqlalchemy.org/en/rel_1_0/dialects/mssql.html#auto-increment-behavior

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 2011-06-27
      • 1970-01-01
      • 2023-03-25
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多