【问题标题】:How to create a unique lowercase functional index using SQLAlchemy on PostgreSQL?如何在 PostgreSQL 上使用 SQLAlchemy 创建唯一的小写函数索引?
【发布时间】:2013-09-11 01:18:44
【问题描述】:

这是我要生成的 SQL:

CREATE UNIQUE INDEX users_lower_email_key ON users (LOWER(email));

从 SQLAlchemy Index documentation 我希望这可以工作:

Index('users_lower_email_key', func.lower(users.c.email), unique=True)

但在我调用metadata.create(engine) 后,表已创建,但此索引未创建。我试过了:

from conf import dsn, DEBUG

engine = create_engine(dsn.engine_info())

metadata = MetaData()
metadata.bind = engine

users = Table('users', metadata,
    Column('user_id', Integer, primary_key=True),
    Column('email', String),
    Column('first_name', String, nullable=False),
    Column('last_name', String, nullable=False),
    )

Index('users_lower_email_key', func.lower(users.c.email), unique=True)

metadata.create_all(engine)

在PostgreSQL中查看表定义发现这个索引没有创建。

\d users
                                   Table "public.users"
   Column   |       Type        |                        Modifiers
------------+-------------------+---------------------------------------------------------
 user_id    | integer           | not null default nextval('users_user_id_seq'::regclass)
 email      | character varying |
 first_name | character varying | not null
 last_name  | character varying | not null
Indexes:
    "users_pkey" PRIMARY KEY, btree (user_id)

如何创建较低的唯一索引?

【问题讨论】:

  • 这个我也很好奇。
  • 你为什么要使用INTEGER 列的小写字母。
  • @TokenMacGuy 我正要问同样的事情,因为这不起作用并且 Postgres 会抛出错误。但是,如果您使用 String 类型,则该示例可以完美运行并且没有麻烦。
  • 我的错;我没有注意到我的示例试图小写一个整数。我已将示例更新为我的实际表格,但也出现了问题。
  • 你能显示所有你的代码吗?另外,您使用的是什么版本的 SQLAlchemy?什么版本的 PostgreSQL?正如我在回答中提到的,使用您的代码创建索引没有任何问题。

标签: postgresql sqlalchemy


【解决方案1】:

我不知道你为什么要索引一个小写的整数列;问题是生成的sql没有typecheck:

LINE 1: CREATE UNIQUE INDEX banana123 ON mytable (lower(col5))
                                                  ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
 'CREATE UNIQUE INDEX banana123 ON mytable (lower(col5))' {}

另一方面,如果您使用实际的字符串类型:

Column('col5string', String),
...
Index('banana123', func.lower(mytable.c.col5string), unique=True)

索引按预期创建。如果出于某种非常奇怪的原因,你坚持使用这个荒谬的索引,你只需要修复类型:

Index('lowercasedigits', func.lower(cast(mytable.c.col5, String)), unique=True)

效果非常好:

CREATE UNIQUE INDEX lowercasedigits ON mytable (lower(CAST(col5 AS VARCHAR)))

【讨论】:

  • 我没有意识到我的示例试图将整数小写。我更新了我的示例以使用一个字符串,其中索引也无法创建。
猜你喜欢
  • 2020-05-12
  • 2015-03-14
  • 1970-01-01
  • 2017-07-12
  • 1970-01-01
  • 2012-12-26
  • 2011-04-28
  • 2021-10-30
  • 2016-09-20
相关资源
最近更新 更多