简体   繁体   English

Flask-SQLAlchemy SQL 服务器唯一标识符

[英]Flask-SQLAlchemy SQL Server UniqueIdentifier

I'm building a webpage which uses SQL Server as the database + Flask for the web framework.我正在构建一个网页,它使用 SQL 服务器作为数据库 + Flask 用于 web 框架。 I want to be able to add users to my webpage, and created a SQLAlchemy class as below:我希望能够将用户添加到我的网页,并创建了一个 SQLAlchemy class 如下:

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

However, when I try to create the tables SQL Server gives me the following error:但是,当我尝试创建表 SQL 服务器给我以下错误:

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) )] sqlalchemy.exc.ProgrammingError: (pyodbc.ProgrammingError) ('42000', "[42000] [Microsoft][ODBC SQL 服务器驱动程序][SQL Server]表 'user' 中的列 'email' 是无效的类型用作索引中的键列。(1919) (SQLExecDirectW); [42000] [Microsoft][ODBC SQL 服务器驱动程序][SQL Server]无法创建约束或索引。请参阅以前的错误。(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) )]

If I remove the "Unique=True" it works fine.如果我删除“唯一=真”它工作正常。 I guess it has something to do with the SQL Server not understanding whats going on in the class or vice-versa.我想这与 SQL 服务器不了解 class 中发生的事情有关,反之亦然。

Any ideas how to make a key Unique in SQL Server from SQLAlchemy任何想法如何在 SQLAlchemy 的 SQL 服务器中制作唯一的密钥

From SQLAlchemy docs :来自SQLAlchemy 文档

SQL Server supports the special string “MAX” within the sqltypes.VARCHAR and sqltypes.NVARCHAR datatypes, to indicate “maximum length possible”. SQL 服务器支持 sqltypes.VARCHAR 和 sqltypes.NVARCHAR 数据类型中的特殊字符串“MAX”,以指示“可能的最大长度”。 The dialect currently handles this as a length of “None” in the base type...方言当前将其处理为基本类型中的“无”长度......

And the api reference for sqlalchemy.dialects.mssql.VARCHAR shows the constructor signature as: api 参考sqlalchemy.dialects.mssql.VARCHAR将构造函数签名显示为:

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

As the default value of length is None and SQLAlchemy uses length=None to signal a max length varchar, all of your String columns are being defined as such, which you can see in the error message that you've posted:由于length的默认值为None并且 SQLAlchemy 使用length=None来表示最大长度 varchar,因此您的所有String列都被定义为这样,您可以在您发布的错误消息中看到:

..email VARCHAR(max) NULL, password VARCHAR(max) NULL ..email VARCHAR(最大) NULL,密码VARCHAR(最大) NULL

From SQL Server docs :来自SQL 服务器文档

Columns that are of the ntext, text, image, varchar(max), nvarchar(max), and varbinary(max) data types cannot be specified as index key columns...不能将 ntext、text、image、varchar(max)、nvarchar(max) 和 varbinary(max) 数据类型的列指定为索引键列...

It goes on to say that they can be used as nonkey index columns in a clustered index, but according to this answer , varchar(max) will store over 2 billion single byte characters.它继续说它们可以用作聚集索引中的非键索引列,但根据这个答案varchar(max)将存储超过 20 亿个单字节字符。 I highly suspect that you don't need to store that many characters in an email field, so I'd suggest that limiting the length of the email column is the way to go here:我高度怀疑您不需要在 email 字段中存储那么多字符,所以我建议限制 email 列的长度是 Z34D1F91FB2E514B8576ZFAB1A75A89A6 的方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM