小编Ser*_*nin的帖子

在Slick 3中的事务中执行非数据库操作

我无法理解新的Slick DBIOActionAPI,它在文档中似乎没有很多例子.我正在使用Slick 3.0.0,我需要执行一些数据库操作以及从数据库接收的数据的一些计算,但所有这些操作都必须在单个事务中完成.我正在尝试执行以下操作:

  1. 对数据库(types表)执行查询.
  2. 对查询结果进行一些聚合和过滤(无法在数据库上进行此计算).
  3. 根据步骤2中的计算执行另一个查询(该messages表 - 由于某些限制,此查询必须在原始SQL中).
  4. 将步骤2和3中的数据加入内存中.

我希望步骤1和3中的查询在事务内执行,因为结果集中的数据必须一致.

我试图用monadic join样式做到这一点.这是我的代码的过度简化版本,但我甚至无法编译:

  val compositeAction = (for {
    rawTypes <- TableQuery[DBType].result
    (projectId, types) <- rawTypes.groupBy(_.projectId).toSeq.map(group => (group._1, group._2.slice(0, 10)))
    counts <- DBIO.sequence(types.map(aType => sql"""select count(*) from messages where type_id = ${aType.id}""".as[Int]))
  } yield (projectId, types.zip(counts))).transactionally
Run Code Online (Sandbox Code Playgroud)
  1. 第一行for理解选择types表中的数据.
  2. for理解的第二行应该对结果进行一些分组和切片,从而产生一个Seq[(Option[String], Seq[String])]
  3. 第三行for理解必须为上一步中的每个元素执行一组查询,特别是,它必须为每个内部值执行单个SQL查询Seq[String].所以在第三行我构建了一个DBIOActions 序列.
  4. yield子句zip小号types从第二步骤和counts从所述第三步.

但是,这种结构不起作用,并且会产生两个编译时错误:

Error:(129, 16) type mismatch; …
Run Code Online (Sandbox Code Playgroud)

database scala slick slick-3.0

25
推荐指数
1
解决办法
3286
查看次数

在RESTful资源中更新复合实体

我有一个具有多个属性的实体,比如说"项目".除了简单的属性,项目可能有一个«状态»列表,其中最后一个是当前的.我有一个Web表单来创建/编辑项目.可以在此表单中更改此项目的所有属性,并且用户还可以为项目添加新状态(但不能更改或删除旧状态).

项目状态是纯粹的复合实体,它们在项目范围之外没有任何独特的含义或标识,并且它们不能直接处理,因此它们显然不值得使用特殊的根REST资源.

根据REST架构,我创建了一个名为/ projects的资源.POST用于创建新项目,PUT用于更改现有项目.

但是,我不希望客户端将项目与其所有历史状态一起推送,首先是因为此集合太重,其次是因为业务逻辑仅允许添加状态,而不是更改或删除它们,因此将项目设置为PUT无论如何,连同其所有状态都没有任何意义.

仅具有新状态的项目也不是一种选择,因为它违反了PUT的幂等性.

我也不喜欢在第二个HTTP请求中发布状态的想法,例如/ project/{id}/status,因为这会从用户的角度打破更新操作的原子性.如果第二个请求在线路上丢失,则项目将与编辑它的用户不一致(属性已更改,但状态保持不变).创建RESTful"事务"对于更新看似单一的实体这一简单任务来说似乎有点过分(并且也容易出错).

这种问题在我的工作中非常普遍,并且可以如此概括:更新复杂的复合实体的REST非常正确和原子的方式是什么,业务逻辑只允许部分更新?

rest restful-architecture

8
推荐指数
2
解决办法
491
查看次数

Haskell 中的存在类型和其他语言中的泛型

我试图使用Haskell/Existentially quantified types 一文来掌握 Haskell 中存在类型的概念。乍一看,这个概念似乎很清楚,有点类似于面向对象语言中的泛型。主要的例子有一个叫做“异构列表”的东西,定义如下:

data ShowBox = forall s. Show s => SB s
 
heteroList :: [ShowBox]
heteroList = [SB (), SB 5, SB True]

instance Show ShowBox where
  show (SB s) = show s
 
f :: [ShowBox] -> IO ()
f xs = mapM_ print xs

main = f heteroList
Run Code Online (Sandbox Code Playgroud)

我对“异构列表”有不同的概念,类似于Scala 中的 Shapeless。但在这里,它只是一个包含在仅添加类型约束的存在类型中的项目列表。它的元素的确切类型并没有体现在它的类型签名中,我们唯一知道的是它们都符合类型约束。

在面向对象的语言中,写这样的东西似乎很自然(Java 中的例子)。这是一个无处不在的用例,我不需要创建包装器类型来处理所有实现某个接口的对象列表。该animals列表中有一个泛型类型List<Vocal>,因此我可以假设它的元素都符合这个Vocal接口:

interface Vocal {

    void voice();
}

class Cat implements Vocal {

    public …
Run Code Online (Sandbox Code Playgroud)

haskell existential-type

6
推荐指数
1
解决办法
185
查看次数

使用 --net=container:containerName 键将 docker 容器附加到另一个容器的网络

我正在阅读 Jaroslaw Krochmalski 所著的《面向 Java 开发人员的 Docker 和 Kubernetes》一书,我偶然发现了以下示例。作者建议创建一个桥接myNetwork网络,然后运行连接到该网络的两个容器(Apache Tomcat 和 BusyBox),如下所示(命令应在单独的终端会话中运行):

$ docker run -it --name myTomcat --net=myNetwork tomcat
$ docker run -it --net container:myTomcat busybox
Run Code Online (Sandbox Code Playgroud)

作者特别指出“我们希望 busybox 容器使用与 Tomcat 使用的网络相同的网络。作为替代方案,我们当然可以使用该--net myNetwork选项显式指定网络名称”。

那么作者建议通过在busybox容器中运行以下命令来检查容器之间的通信:

$ wget localhost:8080
Run Code Online (Sandbox Code Playgroud)

这确实有效,但立即让我感到困惑,因为我们有两个不同的容器,并且不清楚为什么它们通过本地主机进行通信。事实证明,上面提到的带有密钥的命令并--net container:myTomcat没有完全将容器添加到网络中,而是使其在与myTomcat容器相同的 IP 下以某种方式可见。

观察结果证实了这一点,如果您运行docker network inspect myNetwork,您将看到实际上只有一个容器连接到网络:

[
    {
        "Name": "myNetwork",
        ...
        "Containers": {
            "464ed70a0c31784226dc943bcbcb79f7c4666b9d7825183706505731ac06a9bf": {
                "Name": "myTomcat",
                "EndpointID": "a4c384f17c6f8e443a430f130093ff6936bb59b1b54d0f056d1f0b4c703c1489",
                "MacAddress": "02:42:ac:14:00:02",
                "IPv4Address": "172.20.0.2/16",
                "IPv6Address": ""
            }
        },
        ...
    }
]
Run Code Online (Sandbox Code Playgroud)

相反,如果您 …

docker docker-network

4
推荐指数
1
解决办法
1万
查看次数