Python SQLAlchemy CRUD操作与结果分配不一致或没有结果分配

Python SQLAlchemy CRUD操作与结果分配不一致或没有结果分配,python,sqlalchemy,Python,Sqlalchemy,我有一个应用程序,我希望用户能够为博客添加书签/取消书签,但在取消书签后,我不想删除书签记录。因此,在我的书签模型上有一个is_Bookmark属性来确定书签是否处于活动状态 在我的测试文件中,我有 def test\u unbookmark\u a\u blog\u do\u assign(会话): 博客=创建博客(会话) 书签=切换书签(会话,blog\u id=blog.id) 断言len(blog.bookmarks)==1 切换书签(会话,blog\u id=blog.id) 断言le

我有一个应用程序,我希望用户能够为博客添加书签/取消书签,但在取消书签后,我不想删除书签记录。因此,在我的书签模型上有一个
is_Bookmark
属性来确定书签是否处于活动状态

在我的测试文件中,我有

def test\u unbookmark\u a\u blog\u do\u assign(会话):
博客=创建博客(会话)
书签=切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==1
切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==0
这个测试通过了。然而,以下情况不会发生。(唯一的区别是我没有为
切换书签的结果指定变量。

def test\u unbookmark\u a\u blog\u no\u assign(会话):
博客=创建博客(会话)
切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==1
切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==0
它在第二次断言时失败
assert len(blog.bookmarks)==0
。原因是
blog.\u bookmarks[0]。is\u bookmarks
不会在
toggle\u bookmark
功能之外更新,并且仍然是
True
,使其在
blog.bookmarks
中可用。(定义见下文)

对于上下文,我使用的是经典映射:

@dataclass
类别书签:
是否已添加书签:bool=True
blog_id:可选[int]=无
@数据类
班级博客:
_书签:列表[书签]=字段(默认工厂=列表)
def add_书签(自我,书签):
self.\u bookmarks.append(书签)
@财产
def书签(自):
return[bookmark for bookmark in self.\u bookmark if bookmark.is\u bookmark]
...
blog_table=表(
“博客”,
元数据,
列(“id”,整数,主键=True,索引=True))
书签\表格=表格(
“书签”,
元数据,
列(“id”,整数,主键=True,索引=True),
列(“已添加书签”,布尔值,默认值=True),
列(“blog_id”,ForeignKey(“blog.id”),null=True),
)
...
制图员(
博客,
blog_表,
性质={
“\u bookmarks”:关系(Bookmark,back\u populates=“blog”),
},
)
制图员(
书签,
书签_表,
性质={
“blog”:关系(blog,back_populates=“_bookmarks”),
},
)
切换书签功能:

def toggle_书签(数据库会话,*,博客id):
blog=db\u session.query(blog.get)(blog\u id)
bookmark=db_session.query(bookmark.filter)(
Bookmark.blog\u id==blog\u id
).一个或没有
如果书签为“无”:
书签=书签()
blog.add_书签(书签)
db_session.add(博客)
db_session.commit()
返回书签
bookmark.is_bookmark=未书签.is_bookmark
db_session.add(书签)
db_session.commit()
返回书签
我真的很困惑。。。我的直觉告诉我,当查询得到评估时,它有一些作用,但我还没有找到任何证据来支持它。感谢您的帮助。提前谢谢

一个完整的例子:

从数据类导入数据类,字段
从键入import Optional开始,列出
从sqlalchemy导入(
创建(引擎、元数据、表、列、整数、布尔值、ForeignKey)
从sqlalchemy.orm导入映射器、关系、会话生成器
@数据类
类别书签:
是否已添加书签:bool=True
blog_id:可选[int]=无
@数据类
班级博客:
_书签:列表[书签]=字段(默认工厂=列表)
def add_书签(自我,书签):
self.\u bookmarks.append(书签)
@财产
def书签(自):
return[bookmark for bookmark in self.\u bookmark if bookmark.is\u bookmark]
引擎=创建引擎(“sqlite://”)
元数据=元数据(绑定=引擎)
blog_table=表(
“博客”,
元数据,
列(“id”,整数,主键=True,索引=True))
书签\表格=表格(
“书签”,
元数据,
列(“id”,整数,主键=True,索引=True),
列(“已添加书签”,布尔值,默认值=True),
列(“blog_id”,ForeignKey(“blog.id”),null=True),
)
metadata.create_all()
制图员(
博客,
blog_表,
性质={
“\u bookmarks”:关系(Bookmark,back\u populates=“blog”),
},
)
制图员(
书签,
书签_表,
性质={
“blog”:关系(blog,back_populates=“_bookmarks”),
},
)
def切换_书签(db_会话,*,博客id):
blog=db\u session.query(blog.get)(blog\u id)
bookmark=db_session.query(bookmark.filter)(
Bookmark.blog\u id==blog\u id
).一个或没有
如果书签为“无”:
书签=书签()
blog.add_书签(书签)
db_session.add(博客)
db_session.commit()
返回书签
bookmark.is_bookmark=未书签.is_bookmark
db_session.add(书签)
db_session.commit()
返回书签
def创建_博客(会话):
blog=blog()
session.add(博客)
session.commit()
返回博客
def test_unbookmark_a_blog_do_assign(会话):
博客=创建博客(会话)
书签=切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==1
切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==0
def test_unbookmark_a_blog_no_assign(会话):
博客=创建博客(会话)
切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==1
切换书签(会话,blog\u id=blog.id)
断言len(blog.bookmarks)==0
Session=sessionmaker()
test\u unbookmark\u a\u blog\u do\u assign(Session())
测试\u取消标记\u日志\u否\u分配(会话())

核心问题是:

class Bookmark:
    is_bookmarked: bool = True  # <-- This here
克服这种情况的一种方法是使用
字段()
>>> from dataclasses import dataclass, field >>> @dataclass ... class C: ... f: bool = field(default=True) ... >>> C.f True
@dataclass
class Bookmark:
    is_bookmarked: bool = field(default_factory=lambda: True)
    ...