falcon-autocrud:如何处理唯一行?

falcon-autocrud: how to handle unique rows?

我想用 Falcon 创建一个简单的应用程序,它能够处理带有 hostname: ip 条记录的小型 sqlite 数据库。我希望能够替换 sqlite 中的行,所以我决定 hostname 是唯一字段。我有一个 model.py:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String

Base = declarative_base()
DB_URI = 'sqlite:///clients.db'

class Client(Base):
    __tablename__ = 'clients'
    id      = Column(Integer, primary_key=True)
    hostname    = Column(String(50), unique=True)
    ip      = Column(String(50))

我的简单resources.py:

from falcon_autocrud.resource import CollectionResource, SingleResource
from models import *

class ClientCollectionResource(CollectionResource):
    model = Client
    methods = ['GET', 'POST']

当我使用有关 hostname 的更新信息发出 POST 请求时:ip 我收到 Unique constraint violated 错误:

req = requests.post('http://localhost:8000/clients', 
                    headers={'Content-Type': 'application/json'}, 
                    data=json.dumps({'hostname': 'laptop1', 'ip': '192.168.0.33'}));
req.content
>> b'{"title": "Conflict", "description": "Unique constraint violated"}'

有什么方法可以使用 sqlalchemy 替换现有记录吗?或者也许我为这些目的选择了 sqlite 是错误的?

构建 REST-ful API 时,您应该 使用 POST 更新现有资源, POST 到资源应该只创建新资源falcon-autocrud 在这里做正确的事。

而是对单个资源(为 .../clients/<identifier> 注册的 SingleResource 资源)使用 PUT 来更改现有资源。

如果您在 SingleResource 定义中使用 hostname,那么 falcon-autocrud 应该自动使用该列作为标识符(假设您的 SingleResource 子类被称为 ClientResource):

app.add_route('/clients/{hostname}', ClientResource(db_engine))

此时您可以 PUT 新的 ip 值直接使用:

requests.put('http://localhost:8000/clients/laptop1', json={'ip': '192.168.0.33'})

(请注意,requests 直接支持 JSON 请求;json= 关键字参数为您编码为 JSON,而 Content-Type header是在你使用的时候自动为你设置的)。

您可能想要限制为 Client objects 返回的字段。使用唯一的 hostname,您不希望通过同时发送主键列来混淆客户。我会通过在您的资源 类:

上设置 response_fields 属性来限制响应字段
class ClientCollectionResource(CollectionResource):
    model = Client
    response_fields = ['hostname', 'ip']
    methods = ['GET', 'POST']

class ClientResource(SingleResource):
    model = Client
    response_fields = ['hostname', 'ip']

我看到 falcon-autocrud 尚不支持 collection 上更改现有资源的 PATCH 请求(仅支持 "op": "add"),否则也是更改现有条目的另一条途径。