flask-sqlalchemy多数据源原生查询报get_bind() got an unexpected keyword argument ‘bind‘的问题

组件版本:

使用原生方法查询:

db.session.execute("select * from user", bind_arguments={'bind':activity_engine}).fetchall()

报了:get_bind() got an unexpected keyword argument 'bind'异常,查看源码后发现并没有明显异常:

    def execute(
        self,
        statement,
        params=None,
        execution_options=util.EMPTY_DICT,
        bind_arguments=None,
        _parent_execute_state=None,
        _add_event=None,
        **kw
    ):
        r"""Execute a SQL expression construct.

        Returns a :class:`_engine.Result` object representing
        results of the statement execution.

        E.g.::

            from sqlalchemy import select
            result = session.execute(
                select(User).where(User.id == 5)
            )

        The API contract of :meth:`_orm.Session.execute` is similar to that
        of :meth:`_future.Connection.execute`, the :term:`2.0 style` version
        of :class:`_future.Connection`.

        .. versionchanged:: 1.4 the :meth:`_orm.Session.execute` method is
           now the primary point of ORM statement execution when using
           :term:`2.0 style` ORM usage.

        :param statement:
            An executable statement (i.e. an :class:`.Executable` expression
            such as :func:`_expression.select`).

        :param params:
            Optional dictionary, or list of dictionaries, containing
            bound parameter values.   If a single dictionary, single-row
            execution occurs; if a list of dictionaries, an
            "executemany" will be invoked.  The keys in each dictionary
            must correspond to parameter names present in the statement.

        :param execution_options: optional dictionary of execution options,
         which will be associated with the statement execution.  This
         dictionary can provide a subset of the options that are accepted
         by :meth:`_engine.Connection.execution_options`, and may also
         provide additional options understood only in an ORM context.

        :param bind_arguments: dictionary of additional arguments to determine
         the bind.  May include "mapper", "bind", or other custom arguments.
         Contents of this dictionary are passed to the
         :meth:`.Session.get_bind` method.

        :param mapper:
          deprecated; use the bind_arguments dictionary

        :param bind:
          deprecated; use the bind_arguments dictionary

        :param \**kw:
          deprecated; use the bind_arguments dictionary

        :return: a :class:`_engine.Result` object.


        """
        statement = coercions.expect(roles.StatementRole, statement)

        if kw:
            util.warn_deprecated_20(
                "Passing bind arguments to Session.execute() as keyword "
                "arguments is deprecated and will be removed SQLAlchemy 2.0. "
                "Please use the bind_arguments parameter."
            )
            if not bind_arguments:
                bind_arguments = kw
            else:
                bind_arguments.update(kw)
        elif not bind_arguments:
            bind_arguments = {}

        if (
            statement._propagate_attrs.get("compile_state_plugin", None)
            == "orm"
        ):
            # note that even without "future" mode, we need
            compile_state_cls = CompileState._get_plugin_class_for_plugin(
                statement, "orm"
            )
        else:
            compile_state_cls = None

        execution_options = util.coerce_to_immutabledict(execution_options)

        if compile_state_cls is not None:
            (
                statement,
                execution_options,
            ) = compile_state_cls.orm_pre_session_exec(
                self,
                statement,
                params,
                execution_options,
                bind_arguments,
                _parent_execute_state is not None,
            )
        else:
            bind_arguments.setdefault("clause", statement)
            execution_options = execution_options.union(
                {"future_result": True}
            )

        if _parent_execute_state:
            events_todo = _parent_execute_state._remaining_events()
        else:
            events_todo = self.dispatch.do_orm_execute
            if _add_event:
                events_todo = list(events_todo) + [_add_event]

        if events_todo:
            orm_exec_state = ORMExecuteState(
                self,
                statement,
                params,
                execution_options,
                bind_arguments,
                compile_state_cls,
                events_todo,
            )
            for idx, fn in enumerate(events_todo):
                orm_exec_state._starting_event_idx = idx
                result = fn(orm_exec_state)
                if result:
                    return result

            statement = orm_exec_state.statement
            execution_options = orm_exec_state.local_execution_options

        bind = self.get_bind(**bind_arguments)
        ...

 按理说不应该报bind参数异常,后来仔细发现,实际上调用了flask-sqlalchemy中的get_bind()方法

    def get_bind(self, mapper=None, clause=None):
        """Return the engine or connection for a given model or
        table, using the ``__bind_key__`` if it is set.
        """
        # mapper is None if someone tries to just get a connection
        if mapper is not None:
            try:
                # SA >= 1.3
                persist_selectable = mapper.persist_selectable
            except AttributeError:
                # SA < 1.3
                persist_selectable = mapper.mapped_table

            info = getattr(persist_selectable, 'info', {})
            bind_key = info.get('bind_key')
            if bind_key is not None:
                state = get_state(self.app)
                return state.db.get_engine(self.app, bind=bind_key)
        return SessionBase.get_bind(self, mapper, clause)

 应该是组件间版本不兼容导致,直接修改源码为:

    def get_bind(self, mapper=None, clause=None, bind=None):
        """Return the engine or connection for a given model or
        table, using the ``__bind_key__`` if it is set.
        """
        # mapper is None if someone tries to just get a connection
        if mapper is not None:
            try:
                # SA >= 1.3
                persist_selectable = mapper.persist_selectable
            except AttributeError:
                # SA < 1.3
                persist_selectable = mapper.mapped_table

            info = getattr(persist_selectable, 'info', {})
            if bind is not  None:
                state = get_state(self.app)
                return state.db.get_engine(self.app, bind=bind)
            bind_key = info.get('bind_key')
            if bind_key is not None:
                state = get_state(self.app)
                return state.db.get_engine(self.app, bind=bind_key)
        return SessionBase.get_bind(self, mapper, clause, bind)

重新运行,问题解决

或者直接从github上拉取最新代码安装:

git clone https://github.com/pallets/flask-sqlalchemy.git

python .\setup.py install

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值