Я пытаюсь выяснить, как переносить мою собственную реализацию таблицы закрытия с другого языка на Scala с учетом параллелизма.Slick 3 Transaction
У меня есть две модели: Node (id | parentID) и NodeTree (id | ancestor | descendant), где каждая запись напоминает ребро в дереве.
Для каждого нового узла я должен сделать следующее: запросов всех предков (или фильтровать TableQuery для них), а затем добавить NodeTree-Entry (Ребро) для каждого предка
Благодаря Panther я получил до сих пор:
private val nodes = TableQuery[Nodes]
override def create(node: Node): Future[Seq[Int]] =
{
val createNodesAction = (
for
{
parent <- nodes
node <- (nodeTrees returning nodeTrees.map(_.id) into ((ntEntry, ntId) => ntEntry.copy(id = Some(ntId))) += NodeTree(id = None, ancestor = parent.id, descendant = node.id, deleted = None, createdAt = new Timestamp(now.getTime), updatedAt = new Timestamp(now.getTime)))
} yield (node)
).transactionally
db run createNodesAction
}
Но это приводит к несоответствию типа;
тип несоответствие; найдено: slick.lifted.Rep [Long] требуется: Опция [Long]
Еще раз: Все, что я хочу сделать, это: Для каждого ParentNode (= родитель каждого из родителей до последнего предка-узла не имеет родителя!) Я хочу создать запись в nodeTree, чтобы позже я мог легко захватить всех потомков и предков только с помощью другого вызова метода, который фильтрует через NodeTree-Table.
(Просто закрытие таблицы, на самом деле)
редактировать: Это мои модели
case class Node(id: Option[Long], parentID: Option[Long], level: Option[Long], deleted: Option[Boolean], createdAt: Timestamp, updatedAt: Timestamp)
class Nodes(tag: Tag) extends Table[Node](tag, "nodes")
{
implicit val dateColumnType = MappedColumnType.base[Timestamp, Long](d => d.getTime, d => new Timestamp(d))
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def parentID = column[Long]("parent_id")
def level = column[Long]("level")
def deleted = column[Boolean]("deleted")
def createdAt = column[Timestamp]("created_at")
def updatedAt = column[Timestamp]("updated_at")
def * = (id.?, parentID.?, level.?, deleted.?, createdAt, updatedAt) <> (Node.tupled, Node.unapply)
}
case class NodeTree(id: Option[Long], ancestor: Option[Long], descendant: Option[Long], deleted: Option[Boolean], createdAt: Timestamp, updatedAt: Timestamp)
class NodeTrees(tag: Tag) extends Table[NodeTree](tag, "nodetree")
{
implicit val dateColumnType = MappedColumnType.base[Timestamp, Long](d => d.getTime, d => new Timestamp(d))
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def ancestor = column[Long]("ancestor")
def descendant = column[Long]("descendant")
def deleted = column[Boolean]("deleted")
def createdAt = column[Timestamp]("created_at")
def updatedAt = column[Timestamp]("updated_at")
def * = (id.?, ancestor.?, descendant.?, deleted.?, createdAt, updatedAt) <> (NodeTree.tupled, NodeTree.unapply)
}
То, что я хочу сделать, это замыкание таблицы (http://technobytz.com/closure_table_store_hierarchical_data.html), который заполняет его края (nodeTree) автоматически, когда Я создаю узел. Поэтому я не хочу вручную добавлять все эти записи в базу данных, но когда я создаю узел на уровне 5, я хочу, чтобы весь путь (= записи в таблице nodetree) создавался автоматически.
Я надеюсь, что очищает вещи немного :)
Я принимаю ваш ответ, но есть несколько проблем: Во-первых: nt.id = ntId -> ntId имеет тип Long, а опция [Long] нужна здесь. Кроме того, nt.id = ntId -> переназначение в val:/Кроме того, не могли бы вы уточнить ... будет ли обновляться запрос таблицы (если будет больше записей, будет ли он повторно селе?), Или мне нужно будет сделать это вручную ? – Sorona
Отредактирован ответ на адрес, задающий необязательное значение и переназначение на проблему val. На ваш вопрос о выборе нескольких записей в insert_ я не смог найти способ сделать это. Возможно, это связано с тем, что идентификатор, вероятно, извлекается с использованием другой SQL-конструкции ([last_insert_id] (https://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id)). В настоящее время для выбора других элементов из вставленной строки (например, отметки времени) я делаю это вручную, запустив запрос выбора на извлеченный идентификатор. – panther
Значение id не является членом List [models.Node] * sighs * Мне нужно распаковать список или даже сгладить его? Если я попробую его с TableQuery, я даже получаю: несоответствие типа; найдено: slick.lifted.Rep [Long] required: Option [Long] – Sorona