记录flask+sqlachemy+postgres+pytest项目过程中的报错和解决方案
1. sqlalchemy CRUD语法
注意:修改数据库 一定要跟着session.commit()
往表中增加数据
create table(往数据库增加表信息)
new_player = pt(player_name = 'player1',sex='male')
session.add(new_player)
session.commit()
基础查询操作
query(表名)
query(表名.列名) <=> select 列名 from 表名
- 方法一:query+one
---返回的是对象
item_class = session.query(treasure).filter(treasure.ts_name=='maybe').one()
item_class.ts_class --用.去访问字段
--output
'tool '
- 方法二:query+first
---则返回的可以说是一个list?一个tuple一样的东西
item_class = session.query(treasure.ts_class).filter(treasure.ts_name=='maybe').first()
item_class[0] --和list/tuple取值的方法一样,下标取值
--output
'tool '
同时 query+first也可以用于判断是否存在所要查询的值,若不存在返回None。(query+count也可以实现判断是否存在所要查询的值的判断,若不存在则返回0)
- 方法三: query+first()[]
--也就是将方法二直接合并了,这样的话item_class就直接去到了字符串
--返回字符串
item_class = session.query(treasure.ts_class).filter(treasure.ts_name=='maybe').first()[0]
--output
'tool '
4.方法四:query+all()
--查询一个玩家的所有treasure
--返回list
ts_list = session.query(pt.ts_name).filter(pt.player_name==player_name).all()
更新
query(表名)
query(表名.列名) <=> select 列名 from 表名
--将player表中特定的玩家的find_or_not改为false
session.query(player)
.filter(player.player_name == player_name)
.update({'sex': 'male'})
--多值一起修改
session.query(player)
.filter(player.player_name == 'player1')
.update({'player_money':10,'login_at':time.time()})
session.commit() --只有了commit()了数据库才真正修改
(我现在有点怀疑.filter(player.player_name)
可以用.filter('player_name')
代替)
和sql有少许不同,在sql中对于单表的查询
select player_name from player where player_name = 'player1';
没有任何歧义,但是在sqlalchemy中,则可能会发生意想不到的错误(这是我找了4个小时的bug),所以在查询语句中一定要明确查询的表名,尽管只是单表查询filter(player.player_name==‘player1’)
连接join
--返回list
a=session.query(pt.ts_name)
.join(treasure)
.filter(treasure.ts_class=='luck',pt.player_name=='player1').all()
删除
---删除pt表中ts_name是drop_ts_name的这一行数据
session.query(pt).filter(pt.ts_name==drop_ts_name,player_name==player_name).delete()
2. postgres报错及解决方法
- 删除不了数据库
drop database game;
#output
ERROR: database "game" is being accessed by other users
DETAIL: There is 1 other session using the database.
解决方法:
# 先执行:
select pg_terminate_backend(pid) from pg_stat_activity where DATNAME = 'game';
#output
pg_terminate_backend
----------------------
t
(1 row)
# 再执行
drop database game;
- 报错:
(Background on this error at: http://sqlalche.me/e/f405)
看博客有两个原因:
- 密码输入错误了 ,但那种情况下详细的报错应该是:
sqlalchemy.exc.ProgrammingError: (mysql.connector.errors.ProgrammingError) 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) (Background on this error at: http://sqlalche.me/e/f405)
则需要重新设置密码:(可参考)https://blog.csdn.net/tao01230/article/details/46410525
- 我的问题是在于数据类型不匹配
sql的schema中写的是on_sale_or_not是smallint类型,后来在py文件里,写的class
class treasure(Base):
__tablename__ = 'treasure'
ts_name = Column(String(20),primary_key=True)
on_sale_or_not = Column(Boolean)
own_or_not = Column(Boolean)
wear_or_not = Column(Boolean)
中on_sale_or_not之类的写的类型为boolean所以导致了,数据类型不匹配而出现的错误
- 报错:
date boolean这种数据类型找不到,要从
from sqlalchemy import Column,String,Integer,Boolean,Time,ForeignKey,create_engine,PrimaryKeyConstraint
import 数据类型
- 报错
sqlalchemy.exc.InvalidRequestError: SQL expression, column, or mapped entity expected - got '<__main__.player object at 0x10b4be7f0>
在执行如下语句时:
session.query(player).filter(player.player_name=='cyy').one()
解决方案:重新建player表(因为真的疯了 对于另外的表就可以访问,这个就弄死不行,我就重新建表了,没想到还好使)
3. pytest 覆盖率运行报错
(这也是折磨我疯了的一个问题)
问题描述:pytest运行通过,但在运行coverage 的过程中,出现报错说找不到psycopg2模块
####解决方法:
查询博客/文档发现
- 若,pytest运行报错No module named ‘xxx’可能是pytest的路径和python路径不一致的原因
- 可以用which查看一下pytest和python的路径,若不一致,则可以在当前路径下重新安装pytest即可
- 若,pytest运行通过,但使用coverage run -m pytest生成覆盖率时报错,No module named ‘ psycopg2’。
- 解决方法:用pytest的pytest-cov插件即可
安装:pip install pytest-cov
运行:py.test --cov=myproj tests/
post和get的区别
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。
参考链接
post/get参考链接:https://www.cnblogs.com/logsharing/p/8448446.html
pytest-cov参考链接:https://pypi.org/project/pytest-cov/2.0.0/