[英]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.