我有一个基本的个人项目网站,我希望学习一些Web开发基础知识和数据库(SQL)基础知识(如果SQL甚至是正确使用的技术??)。
我已经启动并运行了基本的骨架,但由于我是新手,我想确保以最有效和“正确”的方式做到这一点。
目前,该网站有一个主索引(登陆)页面,用户可以从中选择几个子页面中的一个。为了便于理解,这些子页面中的每一个代表不同的冲浪中断,并且它们各自显示关于该特定中断的相关信息,即波高,风,潮汐。
由于我已经能够成功地抓取这些数据,我的主要问题围绕如何将这些数据插入数据库以供将来使用(历史图表,趋势)?我如何确保以连续的方式(一天/一天)将数据添加到此数据库?我如何使用从较早时间(例如中午)抓取的数据在下午12:05显示/使用而不是再次抓取它?
非常感谢您指出的任何其他提示,指导或资源。
答案 0 :(得分:1)
此类数据称为时间序列。时间序列有专门的数据库引擎,但是观察量不是很大 - (时间戳,波浪高度,风,浪潮,它打破了)元组 - 一个SQL数据库将是完美的。
尝试将数据建模为Postgres或MySQL中的表。首先制作一个表,然后在数据库的GUI客户端中手动插入一些虚假数据。当它看起来正确时,您拥有架构。相应的CREATE TABLE语句是您的DDL。您应该能够针对表生成SELECT查询,从而生成要在webapp上显示的数据。如果这些查询很尴尬,则表明您的架构需要修改。保存您的DDL。它是(部分)源代码的一部分。我想象两个表:冲浪休息列表和观察列表。观察列表中的每一行都将参考冲浪休息列表。如果您使用的是Mac,Sequel Pro
是使用MySQL数据库的一个不错的工具,玩游戏可能是学习使用它的最好方法。
接下来,尝试从Python脚本向表中插入数据。从假数据开始很好,但是要将你的Python脚本从上游源(抓取的结果)读取并插入到表中。你的抓取代码输出了什么?这是一个你可以打电话的功能吗?您可以阅读CSV吗?这将决定这个脚本的工作原理。
如果此导入脚本幂等,它将提供帮助:您可以多次运行它,并且通过插入重复行不会弄得一团糟。如果这是 incremental ,它也会有所帮助:一旦你的数据集变大,重新计算整个事物就会非常昂贵。尝试一次处理导入特定间隔。命令行工具很好。您可以将间隔指定为命令行参数,或从当前时间中计算出来。
此处的一般问题是,将数据从一个系统定期加载到另一个系统,称为 ETL 。你有一个非常简单的例子,并且可以使用非常简单的工具,但如果你想阅读它,那就是它所谓的。相反,如果您可以获得连续的观察流 - 例如,直接来自传感器 - 您将遇到流式摄取问题。
您可以使用Linux子系统cron
使该脚本按计划运行。您将想知道它是否成功运行 - 这会打开另外一组关于监视和警报的蠕虫。有各种开源系统可以让你从你的程序中发出指标,基本上是"嘿,发生这种情况"勾选,查看在图表上绘制的这些指标,并要求通过电子邮件发送/发送短信/分页,如果发生的事情太频繁或太频繁。 (顺便提一下,这些系统是时间序列数据库的主要应用之一)。不要因为这个问题而陷入困境,但请牢记这一点。 Statsd,Grafana和Prometheus是一些让你开始谷歌搜索的名字。您也可以让脚本发送成功或失败的电子邮件,但人们往往会忽略此类电子邮件。
您已经编写了一些与数据库引擎交互的函数。在Python模块中提取这些内容。这构成了数据访问层的基础。在Flask应用程序中重用它。如果您将所有这些内容保存在同一个Git存储库中,这将是最简单的。您可以直接使用所选数据库引擎的Python客户端,也可以使用SQLAlchemy之类的抽象层。这个决定是有争议的,人们会有意见,但只需选择一个。无论您选择哪种数据库API,请了解SQL注入攻击是什么以及如何在查询中使用用户提供的数据,而无需打开SQL注入。您的数据库API的文档应涵盖后者。
Flask应用程序的/
页面将基于SELECT * FROM surf_breaks
之类的SQL查询。为每个特定于特定于休息的页面呈现链接。
您还会有另一个页面,例如/breaks/n
,其中n
标识冲浪中断(按照惯例插入冲浪中断行时会增加的整数)。此页面将基于SELECT * FROM observations WHERE surf_break_id = n
之类的查询。在每种情况下,您都可以在数据访问层中调用函数来获取行列表,然后在模板中迭代这些行并呈现一些HTML。有各种Javascript和Python图形库,您可以将这些行列表输入并从中获取图形(客户端或服务器端)。如果您对一周一周的更改感兴趣,您应该能够在一个SQL查询中表达这一点,并直接从数据库引擎获取该数据集。
为了提高性能,请尽量避免在页面加载过程中出现多个SQL查询。默认情况下,您将通过返回数据库并在每次有人请求时重新计算页面来执行一些不必要的工作。如果这成为问题,您可以在Flask应用程序前添加反向代理缓存。在您的情况下,这很容易,因为用户没有做任何事情导致其内容发生变化。导入新数据时,只需使缓存无效。