问题 使用django从外部数据库将数据提取到模板


我将尝试构建一个Web应用程序,用户可以访问该URL,登录并查看报告和其他信息。但是,报告的数据存储在外部数据库中。这是一个我可以访问的MySQL数据库。

我已经对谷歌进行了一些研究,没有太多运气找到任何例子。我已经完成了连接多个数据库的一些阅读 - https://docs.djangoproject.com/en/dev/topics/db/multi-db/ 所以它看起来我可以连接到数据库确定。

接下来的部分是我被困住的地方。数据库中的数据将一直更新。我不希望能够编辑信息,我也不想覆盖任何东西。我只是希望能够连接到DB拉取所需的信息,然后通过模板查看它以便用户能够看到。首先是因为数据一直在更新,这是一个问题吗? (我希望不是!)

一旦我连接到数据库,最好能够提取数据然后将其放入我可以输出到模板的格式?我是否需要将数据导入模型,然后使用视图进行控制。或者我需要使用JSON或XML转换数据?

我对python / django很新,所以任何帮助都会非常感激。如果您需要更多信息,请提前询问并表示感谢。 :)


11963
2018-05-16 19:52


起源



答案:


没问题!我一直这样做。

至于“不编辑或更新数据”,只是不要向您的应用添加任何会更新数据的内容。 Salem关于在MySQL端使用权限的建议也是一个好主意。

要检索数据,您有两种选择:

1)您可以创建与MySQL数据库中的表对应的Django模型。您可以手动执行此操作,也可以使用manage.py中的“inspectdb”命令为自己提供一个良好的起点。然后做这样的事情:

def myview(request):
  rows = MyModel.objects.using('mysql').all()
  return render_to_response("mytemplate.html", {"rows" : rows })

2)您可以在应用程序中手动管理连接和查询。这在视图中完全有效:

def myview(request):
  conn = MySQLdb.connect("connection info here")
  try:
    cursor = conn.cursor()
    cursor.execute("select * from mytable")
    rows = cursor.fetchall()
  finally:
    conn.close()

  return render_to_response("mytemplate.html", {"rows" : rows})

最后 - Django非常乐意使用MySQL作为数据库。如果你的DBA让Django在同一个数据库中创建它的表,它可能会简化一些事情。


14
2018-05-17 01:16



感谢您的所有回复,给我足够的信息继续。我是否需要设置新的应用程序以将信息提取到新的models.py文件中?此外,当数据被拉入模型时,信息是否会更新每次刷新页面,就好像正在模板上显示一样? - JDavies
你没有 需要 一个单独的MySQL类应用程序,但欢迎您创建它。我正在查看我的代码,并且我将远程资料设置为模型的子模块。 (myapp / models,myapp / models / somethingelse,myapp / models / anotherthing)。那是因为在我的情况下,我在myapp / models中有一些项目来包装来自“somethingelse”和“otherthing”的实例。您还可以创建一个新的应用程序来隔离它,或者您可以只为所有名称添加前缀。 - Chris Curvey
WRT数据更新:如果您使用类似上面的示例,那么答案是“是”。查询将每次都执行并且是最新的。如果您不想要这种行为,则必须添加自己的缓存。 - Chris Curvey
好的,谢谢,我会尝试将模型添加到我现有的应用程序中进行测试。我要在我的设置文件中设置数据库,如何连接到外部数据库?我是否只需添加托管数据库的IP? - JDavies
看到 docs.djangoproject.com/en/dev/topics/db/multi-db。那里有一个例子。保留主数据库的“默认”条目,并为外部数据库保留另一个条目(该示例使用“用户”) - Chris Curvey


答案:


没问题!我一直这样做。

至于“不编辑或更新数据”,只是不要向您的应用添加任何会更新数据的内容。 Salem关于在MySQL端使用权限的建议也是一个好主意。

要检索数据,您有两种选择:

1)您可以创建与MySQL数据库中的表对应的Django模型。您可以手动执行此操作,也可以使用manage.py中的“inspectdb”命令为自己提供一个良好的起点。然后做这样的事情:

def myview(request):
  rows = MyModel.objects.using('mysql').all()
  return render_to_response("mytemplate.html", {"rows" : rows })

2)您可以在应用程序中手动管理连接和查询。这在视图中完全有效:

def myview(request):
  conn = MySQLdb.connect("connection info here")
  try:
    cursor = conn.cursor()
    cursor.execute("select * from mytable")
    rows = cursor.fetchall()
  finally:
    conn.close()

  return render_to_response("mytemplate.html", {"rows" : rows})

最后 - Django非常乐意使用MySQL作为数据库。如果你的DBA让Django在同一个数据库中创建它的表,它可能会简化一些事情。


14
2018-05-17 01:16



感谢您的所有回复,给我足够的信息继续。我是否需要设置新的应用程序以将信息提取到新的models.py文件中?此外,当数据被拉入模型时,信息是否会更新每次刷新页面,就好像正在模板上显示一样? - JDavies
你没有 需要 一个单独的MySQL类应用程序,但欢迎您创建它。我正在查看我的代码,并且我将远程资料设置为模型的子模块。 (myapp / models,myapp / models / somethingelse,myapp / models / anotherthing)。那是因为在我的情况下,我在myapp / models中有一些项目来包装来自“somethingelse”和“otherthing”的实例。您还可以创建一个新的应用程序来隔离它,或者您可以只为所有名称添加前缀。 - Chris Curvey
WRT数据更新:如果您使用类似上面的示例,那么答案是“是”。查询将每次都执行并且是最新的。如果您不想要这种行为,则必须添加自己的缓存。 - Chris Curvey
好的,谢谢,我会尝试将模型添加到我现有的应用程序中进行测试。我要在我的设置文件中设置数据库,如何连接到外部数据库?我是否只需添加托管数据库的IP? - JDavies
看到 docs.djangoproject.com/en/dev/topics/db/multi-db。那里有一个例子。保留主数据库的“默认”条目,并为外部数据库保留另一个条目(该示例使用“用户”) - Chris Curvey


如果数据正在更新,则没有问题。

现在,要从数据库中检索数据,首先必须导入相关模型 在你的意见

from app_name.models import model_name
def view_report(request):
    r_name=request.POST.get('r_name','default_value')
    r=model_name.objects.get(report_name=r_name)
    return render_to_response('url',{'r':r})

在您的模板中

{{r.report_desc}}

1
2018-05-16 20:21





为了使您对数据库的访问权限为“只读”,我想最好的选择是在MySQL端创建一个仅使用SELECT的限制:

GRANT SELECT ON target_database.* TO your_user@'your_host' IDENTIFIED BY 'your_password';

这将确保在任何情况下更新/更改都将成功。

通常,您将数据库表建模为对象,因为这样可以更轻松地使用Python中的数据库记录并为您提供一些抽象,但您可以执行 原始SQL查询 如果你觉得这是正确的事情。

根据您希望如何呈现数据,您可能需要将其转换为某些内容。

如果您希望使应用程序更具动态性(例如,以10秒的间隔检索新数据并将其呈现给用户而不刷新),您可能需要将其转换为更适合与AJAX一起使用的某种格式,如JSON或XML(Django有一些 系列化 准备使用的工具)。如果您只想要一个“静态”应用程序(即:用户点击链接/按钮并转到显示数据的页面,并且要刷新用户必须刷新页面),您可以使用从数据库中检索的对象在你看来。


1
2018-05-16 20:25



有没有办法测试与外部数据库的连接?就像运行脚本一样,我就像使用GUI一样? - JDavies
是的,你可以使用类似的东西 from django.db import connections; c=connections["external_db"].cursor()。您可以将其包装在try / except块中(如果未成功获得任何异常连接)。还检查一下 这个。 - Salem
非常好的细节。新版本的Django 1.10是否适用,是否有更好的方式来做到这一点?我宁愿在settings.py中定义我的外部数据库。 - nomad