【问题标题】:Structuring request JSON for API为 API 构建请求 JSON
【发布时间】:2019-04-17 13:01:47
【问题描述】:

我正在为其他项目构建一个小型 API 来与我们的数据库进行交互。我已经构建了数据库并且 API 运行良好,但是,我返回的数据不是我想要的结构。

我将 Python 与 Flask/Flask-Restful 一起用于 API。 这是我处理交互的 Python 的 sn-p:

class Address(Resource):
    def get(self, store):
        print('Received a request at ADDRESS for Store ' + store )
        conn = sqlite3.connect('store-db.db')
        cur = conn.cursor()
        addresses = cur.execute('SELECT * FROM Sites WHERE StoreNumber like ' + store)     
        for adr in addresses:
            return(adr, 200)

如果我向 /sites/42 端点发出请求,其中 42 是站点 ID,我将收到以下信息:

[
    "42",
    "5000 Robinson Centre Drive",
    "",
    "Pittsburgh",
    "PA",
    "15205",
    "(412) 787-1330",
    "(412) 249-9161",
    "",
    "Dick's Sporting Goods"
]

这是它在数据库中的结构:

最终我想使用列名作为接收到的 JSON 中的键,但我需要一些正确方向的指导,所以我不会在谷歌上搜索模棱两可的术语,希望能找到一些东西。

这是我在向该端点发出请求后希望收到的示例:

{
    "StoreNumber": "42",
    "Street": "5000 Robinson Centre Drive",
    "StreetSecondary": "",
    "City": "Pittsburgh",
    "State": "PA",
    "ZipCode": "15205",
    "ContactNumber": "(412) 787-1330",
    "XO_TN": "(412) 249-9161",
    "RelocationStatus": "",
    "StoreType": "Dick's Sporting Goods"
}

我只是想获得一些指导,了解我是否应该更改我的数据在数据库中的结构(即我看到有些人只是将 JSON 放入他们的数据库中,但我认为这很混乱)或者是否有一个我可以使用更直观的方法来控制我的数据。

使用接受的答案更新代码

class Address(Resource):
    def get(self, store):
        print('Received a request at ADDRESS for Store ' + store )
        conn = sqlite3.connect('store-db.db')
        cur = conn.cursor()
        addresses = cur.execute('SELECT * FROM Sites WHERE StoreNumber like ' + store)     
        for r in res:
            column_names = ["StoreNumber", "Street", "StreetSecondary","City","State", "ZipCode", "ContactNumber", "XO_TN", "RelocationStatus", "StoreType"]
            data = [r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8]]            
            datadict = {column_names[itemindex]:item for itemindex, item in enumerate(data)}
            return(datadict, 200)

【问题讨论】:

  • 使用SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'YourTableName'获取列名
  • 我创建了一个工具来帮助使用 json 公开数据库:github.com/thomaxxl/safrs

标签: python json rest sqlite


【解决方案1】:

您可以将列表转换为 dict,然后将其解析为 JSON 字符串,然后再将其传回。

// These are the names of the columns in your database
>>> column_names = ["storeid", "address", "etc"]

// This is the data coming from the database.
// All data is passed as you are using SELECT * in your query
>>> data = [42, "1 the street", "blah"]

// This is a quick notation for creating a dict from a list
// enumerate means we get a list index and a list item
// as the columns are in the same order as the data, we can use the list index to pull out the column_name
>>> datadict = {column_names[itemindex]:item for itemindex, item in enumerate(data)}

//This just prints datadict in my terminal
>>> datadict

我们现在有一个包含您的数据和列名的命名字典。

{'etc': 'blah', 'storeid': 42, 'address': '1 the street'}

现在将 datadict 转储为字符串,以便将其发送到前端。

>>> import json
>>> json.dumps(datadict)

字典现在已经转换成字符串了。

'{"etc": "blah", "storeid": 42, "address": "1 the street"}'

这不需要更改您的数据库,但脚本需要了解列名或使用某些 SQL 动态检索它们。

如果数据库中的数据以正确的格式传递到前端,那么您不需要更改数据库结构。如果它的格式不正确,那么您可以更改它的存储方式或更改您的 SQL 查询来操作它。

【讨论】:

  • 顺便说一句,看起来您的 SQL 可能容易受到 SQL injection 的攻击,具体取决于变量 store 的传入方式。
  • 我是 Python 新手,您介意在您的示例中评论一下吗?主要在columns、data、datadict声明中。此外,就注入而言,我的 SQL 不会用于生产,我只是制作 PoC 并将其发送给知道他们在做什么的人。 :)
  • 我在代码中添加了一些 cmets,并在答案末尾添加了一些额外的想法。如果您是 python 新手,您可能想查看dict comprehensions。让我知道这是否有帮助。
  • 完美,现在再看一遍。对于未来的观众,我建议为终端输出创建一个单独的代码块,以避免任何混淆。现在就试一试,然后报告结果。
  • 当然,更新了。关于从@nerd100 进一步获取数据库名称有一条有用的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
相关资源
最近更新 更多