Falcon-Autocrud:如何处理独特的行?



我想用Falcon创建一个简单的应用程序,它能够处理带有hostnameip记录的小型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标头)。

您可能希望限制为Client对象返回的字段。使用唯一的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还不支持对集合PATCH更改现有资源的请求(仅支持"op": "add"),否则这也是更改现有条目的另一种途径。

相关内容

  • 没有找到相关文章

最新更新