Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python falcon autocrud:如何处理唯一行?_Python_Sqlite_Sqlalchemy_Falconframework - Fatal编程技术网

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

Python falcon autocrud:如何处理唯一行?,python,sqlite,sqlalchemy,falconframework,Python,Sqlite,Sqlalchemy,Falconframework,我想用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()

我想用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))
from falcon_autocrud.resource import CollectionResource, SingleResource
from models import *

class ClientCollectionResource(CollectionResource):
    model = Client
    methods = ['GET', 'POST']
我的简单
resources.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))
from falcon_autocrud.resource import CollectionResource, SingleResource
from models import *

class ClientCollectionResource(CollectionResource):
    model = Client
    methods = ['GET', 'POST']
当我使用有关
主机名
的更新信息发出POST请求时:
ip
我得到一个违反了
唯一约束的错误:

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
在这里做的事情是正确的

相反,在单个资源上使用
PUT
(为
../clients/
注册的
SingleResource
资源)来更改现有资源

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

在这一点上,您可以使用以下工具直接
放置新的
ip
值:

requests.put('http://localhost:8000/clients/laptop1', json={'ip': '192.168.0.33'})
(请注意,
requests
直接支持JSON请求;
JSON=
关键字参数为您编码为JSON,并且使用时会自动为您设置
内容类型
标题)

您可能希望限制为
客户机
对象返回的字段。使用唯一的
主机名
,您不会希望同时发送主键列而混淆客户端。我会通过在资源类上设置
response\u 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”
),否则这也是更改现有条目的另一种途径