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

时间:2016-07-13 02:00:21

标签: python mysql flask

这是我的代码:

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)

当我跑步时遇到这个错误:

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

1 个答案:

答案 0 :(得分:0)

根据文档,如果子模型中的属性名称重复,则属性将具有重复的列。

例如,如果您这样进行模型,则可以使用联合继承,因为没有命名冲突,并且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',
    }

并将此视图用于子模型,以防止“类型”字段以表格形式显示

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

有了具体的继承,它将可以正常工作。

我可能会考虑如何处理多列ID,但目前无法提供任何估算值。

希望有帮助。