首先。如果这个问题已经得到解答,我深表歉意,但我在任何地方都找不到答案。
我需要在 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% 确定为什么反射不支持这一点。我期望在迁移中它会像以前一样添加它们,但将其包裹在 lower 中。
我并不反对手动编写迁移(因为我假设它是可能的,但不是 100% 确定如何),但有人能指出为什么这不能开箱即用吗?
提前致谢
乔
Update
我通过在迁移中添加以下行解决了这个问题。
op.create_index('ix_users_username', 'users', [sa.text('lower(username)')])
op.create_index('ix_users_email', 'users', [sa.text('lower(email)')])