【问题标题】:Sqlalchemy returns different results of the SELECT command (query.all)Sqlalchemy 返回 SELECT 命令的不同结果(query.all)
【发布时间】:2016-03-28 07:49:58
【问题描述】:

我有网络服务器(512 RAM): FLASK + SQLAlchemy (SQLite) -> uWSGI -> Nginx

问题:Sqlalchemy 返回 SELECT 命令 (query.all) 的不同结果。

例子:

  • 在数据库中添加了几条记录。
  • 我重新加载页面:新记录尚未返回(但旧记录已返回)。
  • 重新加载页面:返回所有记录。很棒。
  • 重新加载页面:再次没有返回新记录。 (但老回来了)。

只要我不重新启动 Flask 应用程序就会发生这种情况。

以下代码:

DECLARATIVE_BASE = declarative_base()
engine = create_engine('sqlite:///database.db')
Session = sessionmaker(bind=engine)
session = Session()

class Order(DECLARATIVE_BASE):
    __tablename__ = 'orders'
    __table_args__ = (
        {'mysql_engine': 'InnoDB', 'sqlite_autoincrement': True, 'mysql_charset': 'utf8'}
    )

    id = Column(INTEGER, autoincrement=True, primary_key=True, nullable=False)  # pylint: disable=invalid-name
    name = Column(TEXT, nullable=False)
    address = Column(TEXT)
    phone = Column(TEXT, nullable=False)
    email = Column(TEXT)
    comment = Column(TEXT)
    totalPrice = Column(DECIMAL(asdecimal=False))
    orderItems = relationship(Orderitem)
    time = Column(TEXT, default=time.strftime("%H:%m %d.%m.%y"))

    def __repr__(self):
        return self.__str__()

    def __str__(self):
        return "<Order(%s)>" % self.__dict__

@app.route('/api/orders', methods=['GET'])
def getAllOrders():
    allOrders = session.query(Order).all()
    return json.dumps(allOrders, cls=new_alchemy_encoder(False, ['orderItems', 'product']), check_circular=False, ensure_ascii=False) #ensure_ascii=False -- for rigth out cyrlic;

【问题讨论】:

    标签: python nginx flask sqlalchemy uwsgi


    【解决方案1】:

    每个 Worker 有一个 SQLAlchemy 会话,并且可能使用 2 个带有 uwsgi 的 Worker。 SQLAlchemy 缓存每个会话的结果,因此 worker 1 的会话返回新结果,因为您已经添加了与此 worker 的记录,但是 worker 2 的会话没有更新并且只返回旧记录。

    解决方案:不要创建全局会话,而是为每个请求创建一个新会话。

    @app.route('/api/orders', methods=['GET'])
    def getAllOrders():
        session = Session()
        allOrders = session.query(Order).all()
        return json.dumps(allOrders, cls=new_alchemy_encoder(False, ['orderItems', 'product']), check_circular=False, ensure_ascii=False) #ensure_ascii=False -- for rigth out cyrlic;
    

    【讨论】:

    • 谢谢你,你是对的!多线程和多进程处理uWSGI的问题。现在我选择了一个不好的方法:禁用多线程和多进程。但是现在 SQLAlchemy 可以正常工作了。我会努力的。
    • @МаксимДанилов:只需为每个请求创建一个新会话
    • SQLA 不会缓存查询结果,但会在会话中遇到同一行时使用标识映射返回同一对象。当重用(全局)会话及其正在进行的事务时,通常“查询不返回插入”的情况源于事务隔离。
    【解决方案2】:

    这应该会有所帮助。 SQLAlchemy 会话未正确关闭!

    @app.teardown_appcontext
    def shutdown_session(exception=None):
        Session.remove()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-14
      • 2014-07-10
      • 2016-11-17
      • 1970-01-01
      • 2017-03-09
      • 2019-07-19
      • 2014-07-07
      • 1970-01-01
      相关资源
      最近更新 更多