我有一个使用 Ecto 和 Postgrex 的库(Postgrex 仅在测试中使用)。
从 Ecto 1 升级到 Ecto 2 后,测试套件开始出现以下错误:
$ mix test
Compiling 4 files (.ex)
Generated ectoo app
** (EXIT from #PID<0.46.0>) shutdown: failed to start child: DBConnection.Ownership.Manager
** (EXIT) exited in: GenServer.call(DBConnection.Ownership.PoolSupervisor, {:start_child, [#PID<0.175.0>, Postgrex.Protocol, [pool: DBConnection.Poolboy, types: true, hostname: "localhost", types: true, otp_app: :ectoo, repo: Ectoo.Repo, adapter: Ecto.Adapters.Postgres, database: "ectoo_test", username: "henrik", pool_timeout: 5000, timeout: 15000, adapter: Ecto.Adapters.Postgres, database: "ectoo_test", username: "henrik", extensions: [{Ecto.Adapters.Postgres.DateTime, []}, {Postgrex.Extensions.JSON, [library: nil]}], port: 5432]]}, :infinity)
** …Run Code Online (Sandbox Code Playgroud) 对于以下查询:
sub_query = from sq in Database.Nestoria,
distinct: sq.lister_url,
select: [sq.place_name,
sq.price,
sq.price_type],
where: fragment("cast(to_char(?, 'YYYYMMDD') AS INTEGER) >= (SELECT cast(to_char(max(inserted_at), 'YYYYMMDD') AS INTEGER) - 1 FROM nestoria)", sq.inserted_at),
where: sq.bedroom_number == 1
query = from un in Database.Underground,
left_join: ne in subquery(sub_query), on: un.station_name_slug == ne.place_name,
select: [ un.lines_id,
un.station_name,
un.display_name,
ne.place_name,
fragment("count(?) as data_count", ne.place_name),
fragment("Avg(CASE WHEN ? = 'weekly' THEN price * ( 31 / 7 ) ELSE price END) AS avg_monthly_price ", ne.price_type)],
group_by: [un.lines_id,
un.station_name, …Run Code Online (Sandbox Code Playgroud) 在 ruby on rails(active record) 中,我们可以通过调用update_counter方法来更新计数器
。例如在 Rails 中,您只需要编写:
# For the Post with id of 5, decrement the comment_count by 1, and
# increment the action_count by 1
Post.update_counters 5, :comment_count => -1, :action_count => 1
# Executes the following SQL:
# UPDATE posts
# SET comment_count = comment_count - 1,
# action_count = action_count + 1
# WHERE id = 5
Run Code Online (Sandbox Code Playgroud)
考虑到我必须更新多列的计数器,有没有什么简单的方法可以在 elixir/phoenix 中做到这一点?
典型的 Elixir Web 应用程序通常有一个 postgresql 后端,带有Ecto与 API 逻辑相结合的查询。
然而,由于每个请求cowboy创建一个子进程(包含应用程序逻辑),因此即使使用池/提供,这是否会产生为n 个并发请求生成n 个psql 线程GenServer的效果?cowboypoolboy
然后,转移到存在应用程序的多个实例的场景(例如 Docker 容器集群),这不会为现有数据库线程总数添加额外的因素吗?
Rails 的schema.rb是获取数据库状态参考的一种非常方便的方法。我可以直接进入 pg 或 mysql 客户端并描述表以获得相同的信息,但它不太方便。
Elixir / Ecto 是否有类似的功能或方式来生成模式表示?
我正在尝试查询属于我的系统中特定用户的所有联赛。
数据设置如下所示:
has_many :users_leagues, Statcasters.UsersLeagues
has_many :leagues, through: [:users_leagues, :league]
Run Code Online (Sandbox Code Playgroud)
所以你可以看到,我有一个 has_many through 关联用户和联赛。
我正在尝试获取用户附加的所有联赛的列表。
在 Rails 中,它看起来像这样:user.leagues它将加载所有附加了当前用户 ID 的联赛。
我如何使用 Ecto、Elixir 和 Phoenix 做到这一点?
这是Postgres的场景
CREATE TABLE "hearings" (
"hearing_id" int4 NOT NULL,
"date" timestamp NOT NULL,
"time" varchar(32),
"committee" varchar(255),
"summary" text,
);
CREATE TABLE "categories" (
"category_id" int4 NOT NULL,
"description" varchar(255) NOT NULL,
"type" varchar(32) DEFAULT 'normal' NOT NULL,
);
CREATE TABLE "hearing_category_link" (
"hearing_id" int4 NOT NULL,
"category_id" int4 NOT NULL,
);
Run Code Online (Sandbox Code Playgroud)
Postgres 查询:
SELECT * FROM
(hearings LEFT JOIN hearing_category_link ON hearings.hearing_id = hearing_category_link.hearing_id )
LEFT JOIN categories ON hearing_category_link.category_id = categories.category_id
Run Code Online (Sandbox Code Playgroud)
到目前为止,我只能用一张表加入当前查询
from h in "hearings", …Run Code Online (Sandbox Code Playgroud) 我想知道如何自动填充时间戳()生成的“updated_at”和“inserted_at”列。
目标是不指定这些值,因为它必须是自动的。我知道如何处理其他列。
schema "users" do
field :newsletter, :boolean, default: false
timestamps(type: :utc_datetime)
end
Run Code Online (Sandbox Code Playgroud)
我试过了
schema "users" do
field :newsletter, :boolean, default: false
field :inserted_at,:utc_datetime, default: :utc_datetime
field :updated_at,:utc_datetime, default: :utc_datetime
end
Run Code Online (Sandbox Code Playgroud)
但它似乎不起作用或运行时未考虑更改:
mix ecto.migrate
Run Code Online (Sandbox Code Playgroud)
我的代码是错误的还是我使用了错误的命令行?
在我的 SQL 模式中,我有
newsletter BOOLEAN DEFAULT FALSE NOT NULL,
inserted_at TIMESTAMP NOT NULL,
updated_at TIMESTAMP NOT NULL,
Run Code Online (Sandbox Code Playgroud)
不管我尝试什么,最后两行都不能有“DEFAULT TIMESTAMP”。
我必须先放下桌子才能工作吗?
我为没有字段的表生成并运行了迁移id(使用该字段league_id作为主键)。我确认迁移按预期进行(检查了 psql 中的数据库,该表确实没有id字段并且league_id是主键)。
当我运行时,Repo.all(League)出现以下错误:
13:01:14.962 [debug] QUERY ERROR source="leagues" db=2.8ms
SELECT l0."id", l0."league_id" FROM "leagues" AS l0 []
** (Postgrex.Error) ERROR 42703 (undefined_column): column l0.id does not exist
有没有办法告诉Repo.all/1没有 id 字段(除了手动构建SELECT *-type 查询之外?)
我们来描述一下问题:
mix phx.new{dev, test}.exs(我正在映射一个现有的数据库)mix phx.gen.context(它创建了一个迁移)的上下文我第一次尝试运行服务器,但它告诉我我有未部署的迁移。
there are pending migrations for repo: Some.Repo.
Try running `mix ecto.migrate` in the command line to migrate it
Run Code Online (Sandbox Code Playgroud)
然后我意识到我不需要它们,因为我已经有了数据库,所以我删除了迁移文件 ( /priv/repo/migrations/*) 并再次尝试。
现在mix ecto.migrations什么都不显示,但它没有删除服务器提示。然后我发现 ecto 在数据库中为迁移创建了一个额外的表,所以我检查了它,它是空的。
我放弃了它并尝试再次运行服务器,但显示了相同的消息。
为了确保这不是 Ecto 问题,我准备了测试并且它们运行得很好,唯一的问题是运行服务器时显示的迁移提示。
我还没有任何端点,因为我计划在验证模型正常工作后使用 GraphQL,但该消息令人困惑。
该迁移是否有任何隐藏文件,或者我是否遗漏了其他内容?
堆栈跟踪:
[error] #PID<0.451.0> running Some.Endpoint (connection #PID<0.449.0>, stream id 1) terminated
Server: localhost:4000 (http)
Request: GET /
** (exit) an exception was raised:
** (Phoenix.Ecto.PendingMigrationError) there are pending migrations for repo: …Run Code Online (Sandbox Code Playgroud)