如何在Node.js和sqlite中实现类似backref的查询?

时间:2019-03-29 08:11:17

标签: sql node.js sqlite

简短版本:Node.js中是否有一个应用程序提供与Python-SQLAlchemy的backref类似的功能?

我实际上想要实现的目标: 我有三个sql表:article,Chapter和subchapter。一篇文章有​​多个章节,而一个章节可以包含多个或零个子章节。 使用SQLAlchemy,它非常简单,UIPercentDrivenInteractiveTransition

animateKeyframes

然后我甚至可以从子章节中访问Article的属性:

models.py

我一直在使用SQLAlchemy,所以我不确定如何使用SQLite进行选择,

class Article(db.Model):
    ...
    chapters = db.relationship('Chapter', backref='mainArticle', lazy=True)

class Chapter(db.Model):
    ...
    articleID = db.Column(db.Integer, db.ForeignKey('article.id'), nullable=False)
    subChapters = db.relationship('subChapter', backref='mainChapter', lazy=True)

class subChapter(db.Model):
    ...
    chapterID = db.Column(db.Integer, db.ForeignKey('chapter.id'), nullable=False)

但是它只是吐出一堆空值...

不幸的是,当前的情况迫使我使用Node.js而不是Python,那么有什么方法可以在Node.js中获得类似的结果吗?

1 个答案:

答案 0 :(得分:0)

在经历了一些试验和错误之后,我确定了一种不太优雅的方法(可能是一种丑陋的方法)来完成这项工作,而无需任何第三方应用程序。 首先,我们使用LEFT JOIN方法选择链接到商品编号的数据库的所有行。 null问题似乎是由不同表(即article.title, chapter.title, subchapter.title)中相同的键名引起的,因此只需使用AS方法将它们区分开即可。

SELECT article.title, 
    chapter.title AS cT, chapter.chapterNumber AS cN,
    subchapter.title AS scT, subchapter.subChapterNumber AS scN
FROM article 
LEFT JOIN chapter ON article.id = chapter.articleID
LEFT JOIN subchapter ON chapter.id = subchapter.chapterID
WHERE article.id = 1
ORDER BY
    chapterNumber ASC,
    subChapterNumber ASC

这将获得一堆条目,其中每个子章节显示一次,每个章节至少显示一次,具体取决于其子章节

现在我们可以编写一个迭代来对数据进行排序。基本思想是形成一个article对象,其chapter属性包含一个章节对象数组,每个属性都包含一个subchapter属性,该属性填充有一个自己的子章节对象数组:

article = {
    "title": "Article Title",
    "chapters": [
        {
            "chapterNumber": 1,
            "subchapters": [
                {
                    "subchapterNumber": 1,
                },
                {
                    "subchapterNumber": 2,
                }
            ]
        },
        {
            "chapterNumber": 2,
            "subchapters": []
        },
    ]
}

然后,我们可以简单地使用article.chapters[0]访问第1章,并使用article.chapters[0].subchapters[0]获得第1.1章。

要实现这一点,组织数据的迭代将是:

article = {"title":entries[0].title, "chapters":[]};
    // First create all the chapter entries for subchapters to depend on.
    for (i in entries) {
        // Use underscore.js utility to determine if this chapter has already been put in.
        if (_.findWhere(article.chapters, {"chapterNumber":entries[i].cN}) == null) {
            // Create a new chapter entry.
            article.chapters.push({"chapterNumber":entries[i].cN,  "subchapters":[]})
        }
    };
    // Then put in place all the subchapters.
    for (i in entries) {
        // Only analyse all the entries that contain a subchapter.
        if (entries[i].scN){
            // Find the corresponding chapter
            chapter = _.findWhere(article.chapters, {"chapterNumber":entries[i].cN})
            // Determine if this subchapter has already been put in.
            if (_.findWhere(chapter.subchapters, {"subchapterNumber":entries[i].scN}) == null) {
                // Create a new subchapter entry.
                chapter.subchapters.push({"chapterNumber":entries[i].cN, "subchapterNumber":entries[i].scN})
            }
        }
    };

如果数据库更复杂,例如每个子章节都包含零个到多个第二个子章节,则相同的主体仍然适用。

现在,单个article对象包含我们可能需要按其顺序显示文章的所有信息。使用pug显示模式的简单运行是:

html
    head
        title= article.title
    body
        each chapter in article.chapters
            li= chapter.title
            each subchapter in chapter.subchapters
                li(style="padding-left:30px")= subchapter.title

这可能不是很有效,但是至少可以完成工作。请告诉我您是否有更好的解决方案。祝大家编码愉快!