繁体   English   中英

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

[英]How to achieve backref-like query in Node.js and sqlite?

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

我实际想要实现的目标:我有三个sql表:文章,章节和子章节。 一篇文章有​​多章,章节可以包含多个或零个子章节。 使用SQLAlchemy,在models.py非常简单

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)

然后我甚至可以从subChapter访问文章的属性:

subchapter = subChapter.query.first()
subchapter.mainChapter.id # Returns the chapter ID
subchapter.mainChapter.mainArticle.id # Returns the article ID

我一直在使用SQLAlchemy,所以我不确定如何选择SQLite,我试过:

app.get('/test/:articleID', (req, res) => {
    let article_id = req.params.articleID;
    let sql = `SELECT article.*, chapter.*, subchapter.*
    FROM article 
    LEFT JOIN chapter ON article.id = chapter.articleID
    LEFT JOIN subchapter ON chapter.id = subchapter.chapterID
    WHERE article.id = ?`;
    db.get(sql, [article_id], (err, article) => {
        res.send(article)
    });
})

但它只是吐了一堆空...

不幸的是,目前的情况迫使我使用Node.js而不是Python,所以有没有办法在Node.js中实现类似的结果?

经过一些试验和错误后,我发现了一种不那么优雅的方式(可能是一种丑陋的方式),可以在没有任何第三方应用的情况下完成工作。 首先,我们使用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属性包含一个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

这可能效率不高,但它至少可以完成工作。 请告诉我你是否知道更好的解决方案。 祝大家愉快!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM