书已收到 ![]()
P10 页
pdm run which python 这个在 windows 11 的 powershell 下运行出错,是否增加个提示,在 windows 下需替换为 pdm run where python ,不知道我的这个算不算勘误,共 greyli 参考。
P24
倒数第四行 编辑排版应该忘了空格了,flaskrun–help 应该是 flask run --help 吧?
第51-52页,重定向test_response函数的路由是/response,52页写的是访问/hello
P143 页 第二个代码块
__tablename = 'contacts'
是否应该是
__tablename__ = 'contacts'
供参考
P132 代码清单 4-8
书上:
class MyBaseForm(FlaskForm):
class Meta:
locales = ['zh']
可以运行,但是 IDE 里面 Meta下会有红波浪线,提示
“Meta”替代类“FlaskForm”中的同名符号
“pdm-playground.app.MyBaseForm.Meta”不可分配给“flask_wtf.form.FlaskForm.Meta”
类型“type[pdm-playground.app.MyBaseForm.Meta]”不可分配给类型“type[flask_wtf.form.FlaskForm.Meta]”PyrightreportIncompatibleVariableOverride
form.py(32, 11): 替代符号
AI 给改成显示继承:
class MyBaseForm(FlaskForm):
class Meta(FlaskForm.Meta):
locales = ['zh']
运行效果也是一样。
供参考
P160 页 表格 5-7
paginate 第一个参数是 statement 吧?我看写得是 select。
我用 statement 比如:stmt = select(Note) 测试了下,符合我想要的。
供参考
P161 页
书上注释:#按名称获取元素 的意思是?
我试了下,元组不能被用文本切片,是我哪里弄错了么?
>>> notes
[(<Note 1 foo>,), (<Note 2 bar>,), (<Note 3 baz>,)]
>>> notes[0][0]
<Note 1 foo>
>>> notes[0]['Note']
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "lib/sqlalchemy/cyextension/resultproxy.pyx", line 54, in sqlalchemy.cyextension.resultproxy.BaseRow.__getitem__
TypeError: tuple indices must be integers or slices, not str
P164
第二排文字,类似于like(),但必须添加 % 是否是指 使用 like() 才需要添加 % 但是 contains() 不需要?
P164
表格中 endnswith 应该是 endswith 供参考
P168
代码:.values(Note.body=‘My body will be updated.’) 改成 values(body=‘My body will be updated’) 否则报错,供参考
另外,此代码块,最后仍需增加 db.session.commit() 才能提交生效 供参考
>>> stmt = (
... update(Note)
... .filter_by(id=2)
... .values(body='My body will be updated.'))
>>> db.session.execute(stmt)
<sqlalchemy.engine.cursor.CursorResult object at 0x0000028D5C357460>
>>> db.session.commit()
页码:176
根据代码清单 5-6 得到
class Author(db.Model):
__tablename__ = 'author'
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(20))
phone: Mapped[Optional[str]] = mapped_column(String(11))
articles: Mapped[list['Article']] = relationship(back_populates='author')
def __repr__(self):
return f'<Author {self.id}: {self.name}>'
class Article(db.Model):
__tablename__ = 'article'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str] = mapped_column(String(50))
body: Mapped[str] = mapped_column(Text)
author_id: Mapped[int] = mapped_column(ForeignKey('author.id'))
author: Mapped['Author'] = relationship(back_populates='articles')
def __repr__(self):
return f'<Article {self.id}: {self.title}>'
下文中创建 Author 和 Article 记录不能正确执行,因为没有建立 Author 和 Article 的逻辑关系:
>>> richard = Author(name='Richard')
>>> eggs = Article(title='Eggs', body='blah...')
>>> snake = Article(title='Snake', body='blah...')
>>> db.session.add_all([richard, eggs, snake])
>>> db.session.commit()
报错如下:
```python
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: article.author_id
[SQL: INSERT INTO article (id, author_id, title, body) VALUES (?, ?, ?, ?), (?, ?, ?, ?)]
[parameters: ('b1c35814fbd24672b2d9d207393640a6', None, 'Eggs', 'blah...', '8aa059e967ae43679a697c7868e97d70', None, 'Snake', 'blah...')]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
猜测作者的意图是设置文章的作者可选填写:
author_id: Mapped[Optional[int]] = mapped_column(ForeignKey(‘author.id’), nullable=True)
author: Mapped[Optional[‘Author’]] = relationship(back_populates=‘articles’)
页码:P203
书本上 app.py 示例程序中
SQLITE_PATH = Path(__file__).resolve() / 'db.sqlite'
应该为
SQLITE_PATH = Path(__file__).parent.resolve() / 'db.sqlite'
否则会得到错误的文件路径
>>> db
<SQLAlchemy sqlite:////Users/zhangkaiqiang/PycharmProjects/notebook/app.py/db.sqlite>
导致 db.create_all() 等方法报错
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file
(Background on this error at: https://sqlalche.me/e/20/e3q8)
GitHub 仓库中给出代码正确。
这里是指参数名是 select。
是指用模型类名获取对应元素。这里 notes[0]['Note'] 写错了,应该是 notes[0]._mapping['Note']
P164 这里是出版社校对的时候乱改,导致偏离了原来的意思。我的原始书稿里是这样写的:
第一版就有很多被乱改的地方,而且也没有跟我确认。
确认的几处已经更新到勘误表,感谢反馈!
感谢反馈!这里的确有问题,可以把 author_id 设为 nullable(Optional 会自动设置 nullable,不用额外设置):
author_id: Mapped[Optional[int]] = mapped_column(ForeignKey(‘author.id’))
也可以先不提交会话,等设置了双向关系以后再 commit。
第326页 代码清单 9-6 第一行 导入没有换行
from faker import Faker import random
第146页 代码清单5-1 获取路径时缺少parent属性:
SQLITE_PATH = Path(__file__).resolve() / 'data.db'
修改:
SQLITE_PATH = Path(__file__).resolve().parent / 'data.db'
第46页 最后一段第1行末尾:
为同一个URL规则指定一个视图函数
修改:
为同一个URL规则指定多个视图函数
