我有一个用户表,例如:
email | username
---------------+----------
[email protected] /cdn-cgi/l/email-protection |
[email protected] /cdn-cgi/l/email-protection |
[email protected] /cdn-cgi/l/email-protection |
我想更新username
场由email
字段,只需切片email
before @
.
email | username
---------------+----------
[email protected] /cdn-cgi/l/email-protection | 123
[email protected] /cdn-cgi/l/email-protection | 123
[email protected] /cdn-cgi/l/email-protection | haha
我尝试使用以下迁移:
defmodule MyApp.Repo.Migrations.AddDefaultUsernameForUsers do
use Ecto.Migration
import Ecto.Query
def up do
from(u in MyApp.User, update: [set: [username: String.split(u.email, "@") |> List.first ]])
|> MyApp.Repo.update_all([])
end
def down do
MyApp.Repo.update_all(MyApp.User, set: [username: nil])
end
end
但在运行迁移时,我收到以下错误:
$ mix ecto.migrate
** (Ecto.Query.CompileError) `List.first(String.split(u.email(), "@"))` is not a valid query expression
我该如何解决这个问题?
@Justin Wood 已经解释了为什么不能在更新查询中使用 Elixir 函数,所以我不会重复。在 PostgreSQL 中,您可以提取之前的文本@
使用substring
带有正则表达式的函数,它将与更新查询一起使用。这比加载记录然后逐一更新它们要快得多,但如果不调整 SQL 片段,则无法与其他数据库引擎一起使用:
from(u in MyApp.User,
update: [set: [username: fragment("substring(? from '^(.*?)@')", u.email)]])
|> MyApp.Repo.update_all([])
postgres=# select substring('12[email protected] /cdn-cgi/l/email-protection' from '^(.*?)@');
substring
-----------
123
(1 row)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)