【问题标题】:Flask-SQLAlchemy SQL Server Using strings as primary keysFlask-SQLAlchemy SQL Server 使用字符串作为主键
【发布时间】:2020-03-04 14:46:52
【问题描述】:

我正在构建一个网页,它使用 SQL Server 作为数据库 + Flask 用于 Web 框架。我希望能够将用户添加到我的网页,并创建了一个 SQLAlchemy 类,如下所示:

from datetime import datetime
from app import db

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(), unique=True)
    password = db.Column(db.String())
    created_at = db.Column(db.DateTime(), default=datetime.now())

    def __repr__(self):
        return self.username

但是,当我尝试创建表时,SQL Server 给了我以下错误:

sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Column 'email' in table 'user' is of a type that is invalid for use as a key column in an index. (1919) (SQLExecDirectW); [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Could not create constraint or index. See previous erro
    rs. (1750)")
    [SQL:
    CREATE TABLE [user] (
            id INTEGER NOT NULL IDENTITY(1,1),
            email VARCHAR(max) NULL,
            password VARCHAR(max) NULL,
            created_at DATETIME NULL,
            PRIMARY KEY (id),
            UNIQUE (email)
    )]

如果我删除 Unique=True 它可以正常工作。我想这与 SQL Server 不了解课堂上发生的事情有关,反之亦然。

任何想法如何在 SQLAlchemy 中使一个键在 SQL Server 中唯一?

【问题讨论】:

    标签: python sql-server sqlalchemy


    【解决方案1】:

    来自SQLAlchemy docs

    SQL Server 支持在 sqltypes.VARCHAR 和 sqltypes.NVARCHAR 数据类型,表示“最大 长度可能”。方言目前将其处理为长度 基本类型中的“无”...

    sqlalchemy.dialects.mssql.VARCHAR 的 api 引用显示构造函数签名为:

    class sqlalchemy.dialects.mssql.VARCHAR(length=None, collation=None, convert_unicode=False, unicode_error=None, _warn_on_bytestring=False, _expect_unicode=False)
    

    由于length 的默认值为None 并且SQLAlchemy 使用length=None 来表示最大长度的varchar,因此您的所有String 列都被这样定义,您可以在错误消息中看到您已发布:

    ..email VARCHAR(max) NULL,密码 VARCHAR(max) NULL

    来自SQL Server docs

    ntext、text、image、varchar(max)、 nvarchar(max) 和 varbinary(max) 数据类型不能指定为 索引键列...

    接着说它们可以用作聚集索引中的非键索引列,但根据this answervarchar(max) 将存储超过 20 亿个单字节字符。我高度怀疑您不需要在电子邮件字段中存储那么多字符,所以我建议限制电子邮件列的长度是这里的方法:

    email = db.Column(db.String(256), unique=True)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 2021-06-10
      • 2017-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多