【发布时间】:2017-06-28 10:37:23
【问题描述】:
首先。抱歉,如果这个问题已经得到解答,但我在任何地方都找不到答案。
我需要在 Flask-SQLAlchemy 对象上定义一个小写索引。
我遇到的问题是我需要将模型用户名和电子邮件字段存储为小写,以便我可以使用User.query.filter(func.lower(username) == func.lower(username)).first() 进行检查
到目前为止,我一直只是通过将这些字段插入为小写来处理这个问题,但在这个特定的例子中,我需要用户名来保留定义它的大小写。
我认为我在正确的轨道上,但遇到了一个我以前从未见过的问题。
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
# Indexes for username and email are defined below User
# They are functional lowercase indexes
username = db.Column(db.String(32))
email = db.Column(db.String(255))
password_hash = db.Column(db.String(255))
...
db.Index('ix_users_username', func.lower(User.username), unique=True)
db.Index('ix_users_email', func.lower(User.email), unique=True)
我看不出这有什么问题。我猜func.lower() 要求索引的定义与我在其他搜索中可以分辨的内容分开。
现在问题来了,当我运行迁移时出现以下错误:
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'users'
.../lib/python3.4/site-packages/alembic/util/messaging.py:69: UserWarning: autogenerate skipping functional index ix_users_email; not supported by SQLAlchemy reflection
warnings.warn(msg)
.../lib/python3.4/site-packages/alembic/util/messaging.py:69: UserWarning: autogenerate skipping functional index ix_users_username; not supported by SQLAlchemy reflection
我不是 100% 确定为什么反射不支持这一点。我期望在我的迁移中它会像以前一样添加它们,但它会被包裹在较低的位置。
我并不反对手动编写迁移(因为我假设它可能,但不是 100% 确定如何)但是谁能指出为什么这不能开箱即用?
提前致谢 乔
更新
我通过在迁移中添加以下行来解决这个问题。
op.create_index('ix_users_username', 'users', [sa.text('lower(username)')])
op.create_index('ix_users_email', 'users', [sa.text('lower(email)')])
【问题讨论】:
-
您需要手动编写迁移。我猜它不受支持,因为很难解析函数索引的表达式。 SQLAlchemy 从内存表示中呈现 SQL;它不会反过来。
-
谢谢@univerio。我以为会是这种情况,只是有点困惑,因为我以为它会更简单。
-
@univero。我已经修改了迁移,一切都很好。不过有一件事。我已经删除了索引的定义,因为 Alembic 经常抱怨它。我只是在列定义上使用默认值 (..., index=True, unique=True)。这是你会做的吗?
-
没有。您的模型应该反映您的数据库模式所处的确切状态,以便您可以执行
metadata.create_all()来创建一个新的数据库。如果您想消除警告,可以使用include_object排除您的索引。 -
完美!这也是我得出的结论。这已经成功了,感谢您的链接。如果您想要回答的分数,请随意。我可以通过我添加迁移的确切方式向答案发送编辑。我认为这可能是有用的答案。
标签: python postgresql flask sqlalchemy alembic