简体   繁体   English

如何使用flask_sqlalchemy定义`ENUM`字段?

[英]How to define `ENUM` field using flask_sqlalchemy?

Here is my code:这是我的代码:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import enum

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:root1234@localhost/kaka_db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db = SQLAlchemy(app)

class UserType(enum.Enum):
    puTongUser      = 0
    guanLiYuan      = 1
    superGuanLiYuan = 2
    changJia        = 3

class User(db.Model):
    __talbename__ = 'user_table'
    id          = db.Column(db.Integer, primary_key=True, autoincrement=True)
    userName    = db.Column(db.String(80), unique=True, nullable=False)
    passWord    = db.Column(db.String(80), nullable=False)
    phone       = db.Column(db.String(80))
    email       = db.Column(db.String(80), unique=True)
    userType    = db.Column(db.Enum(UserType))
    code        = db.Column(db.String(80), unique=True)
    pushToken   = db.Column(db.String(80))
    token       = db.Column(db.String(80))
    regiserType = db.Column(db.Integer, unique=True)
    userMoney   = db.Column(db.Float)

    def __init__(self, username, password, phone = None, email = None, code = None, pushToken = None, userType = 0, registerType = 0, userMoney = 0.0):
        self.userName = username
        self.passWord = password
        self.phone = phone
        self.email = email
        self.code = code
        self.pushToken = pushToken
        self.userType = userType
        self.regiserType = registerType
        self.userMoney = userMoney

db.create_all()
db.session.commit()


if __name__ == '__main__':
    app.run(debug = True)

when i run i meet this error:当我运行时,我遇到了这个错误:

Traceback (most recent call last):
  File "C:\Users\elqstux\workspace\Kaka\server.py", line 41, in <module>
    db.create_all()
  File "C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py", line 972, in create_all
    self._execute_for_all_tables(app, bind, 'create_all')
  File "C:\Python27\lib\site-packages\flask_sqlalchemy\__init__.py", line 964, in _execute_for_all_tables
    op(bind=self.get_engine(app, bind), **extra)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\schema.py", line 3745, in create_all
    tables=tables)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1856, in _run_visitor
    conn._run_visitor(visitorcallable, element, **kwargs)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\base.py", line 1481, in _run_visitor
    **kwargs).traverse_single(element)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\visitors.py", line 121, in traverse_single
    return meth(obj, **kw)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\ddl.py", line 720, in visit_metadata
    _ddl_runner=self)
  File "C:\Python27\lib\site-packages\sqlalchemy\event\attr.py", line 256, in __call__
    fn(*args, **kw)
  File "C:\Python27\lib\site-packages\sqlalchemy\util\langhelpers.py", line 546, in __call__
    return getattr(self.target, self.name)(*arg, **kw)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\sqltypes.py", line 1038, in _on_metadata_create
    t = self.dialect_impl(bind.dialect)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\type_api.py", line 361, in dialect_impl
    return self._dialect_info(dialect)['impl']
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\type_api.py", line 403, in _dialect_info
    impl = self._gen_dialect_impl(dialect)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\type_api.py", line 412, in _gen_dialect_impl
    return dialect.type_descriptor(self)
  File "C:\Python27\lib\site-packages\sqlalchemy\engine\default.py", line 359, in type_descriptor
    return sqltypes.adapt_type(typeobj, self.colspecs)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\type_api.py", line 1186, in adapt_type
    return typeobj.adapt(impltype)
  File "C:\Python27\lib\site-packages\sqlalchemy\sql\sqltypes.py", line 1181, in adapt
    **kw)
  File "C:\Python27\lib\site-packages\sqlalchemy\dialects\mysql\base.py", line 1486, in __init__
    values, length = self._init_values(enums, kw)
  File "C:\Python27\lib\site-packages\sqlalchemy\dialects\mysql\base.py", line 1401, in _init_values
    q = e[0]
  File "C:\Python27\lib\site-packages\enum\__init__.py", line 393, in __getitem__
    return cls._member_map_[name]
KeyError: 0

According to documentation, if you have duplicate property names in child model, properties will have columns duplicated.根据文档,如果您在子模型中有重复的属性名称,则属性将具有重复的列。

For example, if you do your models like this it'll work with joined inheritance, as there are no naming conflicts and SQLAlchemy does not have to map two columns into one property::例如,如果你像这样做你的模型,它将使用连接继承,因为没有命名冲突并且 SQLAlchemy 不必将两列映射到一个属性中:

class Parent(db.Model):
    __tablename__ = 'parent'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50))
    type = db.Column(db.String(50))

    __mapper_args__ = {
        'polymorphic_identity': 'base',
        'polymorphic_on': type
    }

class Child(Parent):
    __tablename__ = 'child'
    child_id = db.Column(db.Integer, db.ForeignKey('parent.id'), primary_key=True)
    text = db.Column(db.String(50))

    __mapper_args__ = {
        'polymorphic_identity': 'child',
    }

And use this view for child model to prevent 'type' field being exposed in forms并将此视图用于子模型以防止在表单中公开“类型”字段

class PolyModel(sqlamodel.ModelView): excluded_form_columns = ('type',)类 PolyModel(sqlamodel.ModelView):excluded_form_columns = ('type',)

With concrete inheritance it will just work without any problems.通过具体的继承,它可以毫无问题地工作。

I might think how to handle multi-column IDs, but can't provide any estimation right now.我可能会考虑如何处理多列 ID,但现在无法提供任何估计。

Hope it helps.希望它有帮助。

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

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