本文将介绍我如何知道是否可以禁用SQLALCHEMY_TRACK_MODIFICATIONS?的详细情况,特别是关于怎么知道sql是否可以执行的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您
本文将介绍我如何知道是否可以禁用SQLALCHEMY_TRACK_MODIFICATIONS?的详细情况,特别是关于怎么知道sql是否可以执行的相关信息。我们将通过案例分析、数据研究等多种方式,帮助您更全面地了解这个主题,同时也将涉及一些关于FAQ(80):java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification、flask+flask_sqlalchemy+flask_script+flask_migrate 创建一个flask项目(一)、flask_sqlalchemy model序列化、flask_sqlalchemy 查询结果转dict 终极解决方案的知识。
本文目录一览:- 我如何知道是否可以禁用SQLALCHEMY_TRACK_MODIFICATIONS?(怎么知道sql是否可以执行)
- FAQ(80):java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification
- flask+flask_sqlalchemy+flask_script+flask_migrate 创建一个flask项目(一)
- flask_sqlalchemy model序列化
- flask_sqlalchemy 查询结果转dict 终极解决方案
我如何知道是否可以禁用SQLALCHEMY_TRACK_MODIFICATIONS?(怎么知道sql是否可以执行)
每次我运行使用Flask-
SQLAlchemy的应用程序时,都会收到以下警告,提示该SQLALCHEMY_TRACK_MODIFICATIONS
选项将被禁用。
/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.5/site-packages/flask_sqlalchemy/__init__.py:800: UserWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True to suppress this warning. warnings.warn(''SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True to suppress this warning.'')
我试图找出此选项的作用,但Flask-SQLAlchemy文档尚不清楚该跟踪的用途。
SQLALCHEMY_TRACK_MODIFICATIONS
如果设置为True(默认值),Flask-SQLAlchemy将跟踪对象的修改并发出信号。这需要额外的内存,如果不需要,可以将其禁用。
如何确定我的项目是否需要,SQLALCHEMY_TRACK_MODIFICATIONS = True
或者是否可以安全地禁用此功能并在服务器上节省内存?
答案1
小编典典您的应用程序很可能没有使用Flask-SQLAlchemy事件系统,因此可以安全地关闭它。您需要审核代码以进行验证-
您正在寻找与models_committed
或before_models_committed
挂钩的任何内容。如果确实发现您正在使用Flask-
SQLAlchemy事件系统,则可能应该更新代码以改为使用SQLAlchemy的内置事件系统。
从Flask-SQLAlchemy 2.1开始None
,默认值为,这是一个伪造的值,因此事件系统 被禁用
。在旧版本中,默认值为True
,因此您需要明确禁用它。
但是,在这两种情况下,除非将警告明确设置为,否则警告都不会消失False
。为此,请添加:
SQLALCHEMY_TRACK_MODIFICATIONS = False
到您的应用程序配置。
背景-警告告诉您的是以下内容:
Flask-
SQLAlchemy有其自己的事件通知系统,该系统在SQLAlchemy之上分层。为此,它跟踪对SQLAlchemy会话的修改。这会占用额外的资源,因此该选项SQLALCHEMY_TRACK_MODIFICATIONS
允许您禁用修改跟踪系统。
更改的理由有三点:
使用Flask-SQLAlchemy的事件系统的人并不多,但是大多数人没有意识到他们可以通过禁用它来节省系统资源。因此,更明智的默认设置是禁用它,想要它的人可以打开它。
Flask-SQLAlchemy中的事件系统存在相当多的错误(请参阅下面提到的请求请求中与之相关的问题),需要为很少有人使用的功能进行额外的维护。
在v0.7中,SQLAlchemy本身添加了功能强大的事件系统,包括创建自定义事件的功能。理想情况下,Flask-SQLAlchemy事件系统除了创建一些自定义的SQLAlchemy事件挂钩和侦听器外,无所不用其事,然后让SQLAlchemy自己管理事件触发器。
您可以在有关开始触发此警告的请求请求的讨论中看到更多信息。
FAQ(80):java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification
2018 年 8 月 31 日
1、日志:
2018-04-13 20:00:55.757:WARN:oejs.ServletHandler:/g01-web/admin/activityManager/sendActivity.jsp
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at org.apache.jsp.admin.activityManager.sendActivity_jsp._jspService(sendActivity_jsp.java:146)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:111)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:403)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:492)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:378)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
at org.eclipse.jetty.server.Server.handle(Server.java:370)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:667)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
at java.lang.Thread.run(Thread.java:745)
2、解决方法:
1)线程的 bug;
源码:
(在遍历对象时,同时修改对象的数据)
for(ActivityInfo info : list){
if(info.getActivityId() == Integer.parseInt(activityId)){
System.out.println("del-info:"+info);
list.remove(info);
accountService.notifyLogonPlayerActivity(ActivityNotifyType.FORCE_ACTIVITY.getCode(),info.getActivityId());
break;
}
}
2)修改:
for(ActivityInfo info : list){
if(info.getActivityId() == Integer.parseInt(activityId)){
System.out.println("del-info:"+info);
delActivity = info;
accountService.notifyLogonPlayerActivity(ActivityNotifyType.FORCE_ACTIVITY.getCode(),info.getActivityId());
break;
}
}
list.remove(delActivity);
改为:跳出循环体后再修改对象。
3)foreach 的快速失败,
阿里巴巴 java 开发手册建议:
7. 【强制】不要在 foreach 循环里进行元素的 remove /add 操作。 remove 元素请使用 Iterator
方式,如果并发操作,需要对 Iterator 对象加锁。
flask+flask_sqlalchemy+flask_script+flask_migrate 创建一个flask项目(一)
最近开始学习flask, 做一下记录目前这个并不完善,后期会慢慢把这个项目该有的都搭建起来, 目前只是记录flask项目使用,有些详细的我可能也讲不出来,慢慢会去维护补充。如果时间充足,会用我的思路去做一个项目练习。
文件名可能不太规范。
1. 文件结构
- 静态文件的默认文件夹:
static
- 静态文件的默认访问前缀:
/static
- 模板文件的默认文件夹:
templates
testWeb # 项目文件 ---- app # 主目录
---- model # 模型问价夹
---- user.py # 用户模型
---- dash.py # app 创建函数文件
---- handlers.py # 逻辑函数文件, 相当于djano 的 view
---- index.py # 没用,忘记删了
---- myRoutes.py # 路由文件
---- test.py # 没用忘记删了
---- config # 配置文件
---- __init__.py # 主配置写在这里
---- migrations # 使用manage 管理项目的时候自己创建的,主要记录数据迁移版本
---- static # 静态文件
---- templates # html
---- manage.py # 项目管理文件, 使其像diango的 python manage.py 一样使用
2. config.py 文件内容
DIALECT = 'MysqL' # 使用MysqL DRIVER = 'pyMysqL' # 使用 pyMysqL 连接数据库 USERNAME = 'root' # 用户名 PASSWORD = '295213' # 密码 HOST = 'localhost' # ip PORT = '3306' # 端口 DATABASE = 'hr' # 数据库名 # 数据库连接配置 sqlALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format( DIALECT, DRIVER, USERNAME, PASSWORD, HOST, PORT, DATABASE ) sqlALCHEMY_TRACK_MODIFICATIONS = False
注意: 数据库 hr 必须线创建。
2. dash.py 文件内容及注释
from flask import Flask from flask_cors import CORS from flask_sqlalchemy import sqlAlchemy import config # 因为config配置是直接写在__init__ 中的所以直接导入即可 # 创建db db = sqlAlchemy() # 取消跨域请求问题 def create_app(): # 创建app app = Flask(__name__) # 导入配置文件 app.config.from_object(config) # 解决跨域请求问题 CORS(app, resources=r'/*') # 数据库绑定app db.init_app(app) # 导入路由 from . import myRoutes # 注册路由 myRoutes.register(app) return appView Code
3. user.py 数据库表
from app.dash import db class Users(db.Model): __tablename__ = "users" # 创建时候的表名 username = db.Column(db.VARCHAR(200), primary_key=True, comment="用户名") def __init__(self, username): self.username = usernameView Code
4. handlers.py 逻辑处理
from app.model.user import Users def index(): users = Users.query.filter() print(users) return users.first().usernameView Code
flask_sqlalchemy model序列化
import datetime
class SerializrAbleMixin(object):
"""A sqlAlchemy mixin class that can serialize itself as a JSON object"""
# args 自定义序列化字段 is_except 序列化是否排除字段 is_hump 返回是否用驼峰命名
def to_dict(self, *args, is_except=False, is_hump=False):
"""
序列化
:param args: 自定义序列化字段
:param is_except: 序列化是否根据args排除字段
:param is_hump: 返回是否用驼峰命名
:return: dict
"""
value = dict()
for column in self.__table__.columns:
attribute = getattr(self, column.name)
if isinstance(attribute, datetime.datetime):
attribute = str(attribute)
if is_hump is True:
column_name = self.__hump(column.name)
else:
column_name = column.name
if not args:
value[column_name] = attribute
else:
if is_except is False:
if column.name in args:
value[column_name] = attribute
else:
if column.name not in args:
value[column_name] = attribute
return value
def from_dict(self, attributes):
"""Update the current instance base on attribute->value by *attributes*"""
for attribute in attributes:
setattr(self, attribute, attributes[attribute])
return self
def __hump(self, column_name):
column_list = column_name.split('_')
for key in range(len(column_list)):
if key != 0:
column_list[key] = column_list[key].capitalize()
return ''.join(column_list)
使用
class ClassName(db.Model, SerializrAbleMixin):
flask_sqlalchemy 查询结果转dict 终极解决方案
之前为了学习Python,试着拿Flask作框架搞小网站,感觉还不错,基本就抛弃了PHP。前段时间做了一个微信小程序,想着yii框架拿来写几十个小接口是不是浪费了,就继续用flask写api了,哪想到填坑无数啊。
Python的ORM框架就属Sqlalchemy牛逼,网上资料也多,想着和yii里面应该差不多,就拿来用了。第二天万万没想到,php里面简单的一句asArray就能解决的问题,flask_sqlalchemy居然没有解决方案,查询的结果对象无法直接JSON序列化。这期间从南到北地找,大部分解决方案都是做一个JSON.dumps的Encoder方法,来转化restult对象,无意中看见https://www.cnblogs.com/wancy86/p/6421792.html 这个帖子,说queryresult对象加入了json属性,欣喜万分,搞了一晚上也没找到这个方法。
原文链接:https://www.cnblogs.com/eating-gourd/p/9997751.html
咳咳,正文:
网上的方法主要问题在于只能处理result对象或model对象之一,当查询某个表全部字段时,如
1 db.session.query(User).filter().all()
其返回User这个类的对象列表,而查询某些字段或者多表连接时,如:
1 db.session.query(User.UserID,User.UserName).filter().all()
其返回result对象的列表,这两种情况下,对象的属性不同,导致很多情况下只能适应一种返回。今天趁闲着没事,把两种情况的查询结果转dict作了一下整理,封装为一个queryToDict函数,并同时支持all()返回的列表和first()返回的单个对象结果:
from datetime import datetime as cdatetime #有时候会返回datatime类型
from datetime import date,time
from flask_sqlalchemy import Model
from sqlalchemy.orm.query import Query
from sqlalchemy import DateTime,Numeric,Date,Time #有时又是DateTime
def queryToDict(models):
if(isinstance(models,list)):
if(isinstance(models[0],Model)):
lst = []
for model in models:
gen = model_to_dict(model)
dit = dict((g[0],g[1]) for g in gen)
lst.append(dit)
return lst
else:
res = result_to_dict(models)
return res
else:
if (isinstance(models, Model)):
gen = model_to_dict(models)
dit = dict((g[0],g[1]) for g in gen)
return dit
else:
res = dict(zip(models.keys(), models))
find_datetime(res)
return res
#当结果为result对象列表时,result有key()方法
def result_to_dict(results):
res = [dict(zip(r.keys(), r)) for r in results]
#这里r为一个字典,对象传递直接改变字典属性
for r in res:
find_datetime(r)
return res
def model_to_dict(model): #这段来自于参考资源
for col in model.__table__.columns:
if isinstance(col.type, DateTime):
value = convert_datetime(getattr(model, col.name))
elif isinstance(col.type, Numeric):
value = float(getattr(model, col.name))
else:
value = getattr(model, col.name)
yield (col.name, value)
def find_datetime(value):
for v in value:
if (isinstance(value[v], cdatetime)):
value[v] = convert_datetime(value[v]) #这里原理类似,修改的字典对象,不用返回即可修改
def convert_datetime(value):
if value:
if(isinstance(value,(cdatetime,DateTime))):
return value.strftime("%Y-%m-%d %H:%M:%S")
elif(isinstance(value,(date,Date))):
return value.strftime("%Y-%m-%d")
elif(isinstance(value,(Time,time))):
return value.strftime("%H:%M:%S")
else:
return ""
dit = dict((g[0],g[1]) for g in gen)相关代码也是之前查找资料获得,现在找不到出处了,作者可以联系我。
滚去学雅思了,代码写得较快,欢迎指出bug
参考资源:
[1] https://stackoverflow.com/questions/5022066/how-to-serialize-sqlalchemy-result-to-json
[2] https://segmentfault.com/q/1010000007459402/a-1020000007460322
关于我如何知道是否可以禁用SQLALCHEMY_TRACK_MODIFICATIONS?和怎么知道sql是否可以执行的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于FAQ(80):java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification、flask+flask_sqlalchemy+flask_script+flask_migrate 创建一个flask项目(一)、flask_sqlalchemy model序列化、flask_sqlalchemy 查询结果转dict 终极解决方案的相关知识,请在本站寻找。
本文标签: