When you say your first execute function doesn't work, what do you
mean? Do you get an error? Do the results not show up in the database?

I don't think there's any need for session.begin()

http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.begin

Simon

On Thu, Feb 15, 2018 at 12:33 PM,  <eugene.de...@gmail.com> wrote:
> Hello, Simon!
> Where did you read that I was using Flask?
> I just write about it like example few posts ago.
> Anyway.
> I try another variant without decorator - just execute function
> def execute(statement, **kwargs):
>     session = SESSION()
>     session.begin(subtransactions=True)
>     kwargs['tries'] = kwargs.get('tries', 0)
>     fetch = kwargs.get('fetch', 'all')
>     try:
>         result = session.execute(statement)
>         if fetch == 'all':
>             return result.fetchall()
>         elif fetch is False:
>             return True
>         elif fetch == 'count':
>             return result
>         return result.fetchone()
>     except ResourceClosedError:
>         session.rollback()
>         session.close()
>         time.sleep(.1)
>         print('try number {}'.format(kwargs['tries']))
>         if kwargs['tries'] < 100:
>             kwargs['tries'] += 1
>             return execute(statement, **kwargs)
>         return list()
>     except Exception as e:
>         session.rollback()
>         session.close()
>         print(e)
>         print(statement)
>     finally:
>         if session.is_active:
>             session.commit()
>             session.close()
> but that not help too. Idk why that not work.
>
> I try another variant:
>
> def execute(statement, **kwargs):
>     fetch = kwargs.get('fetch', 'all')
>     with engine.connect() as session:
>         result = session.execute(statement)
>         if fetch == 'all':
>             return result.fetchall()
>         elif fetch is False:
>             return list()
>         elif fetch == 'count':
>             return result
>         return result.fetchone()
>
> But same error. That variant must always close connection after return, but
> problem in something another.
>
>
>
> четверг, 15 февраля 2018 г., 13:21:51 UTC+3 пользователь Simon King написал:
>>
>> Personally I wouldn't use decorators for this. I would make every
>> function that needs to interact with the database take an explicit
>> session parameter, and I would use the facilities of the web framework
>> to create the session at the beginning of the request and close it at
>> the end. I've never used Flask, but I see it has a "signals" mechanism
>> (http://flask.pocoo.org/docs/0.12/api/#signals) with request_started
>> and request_finished events. You could use the request_started signal
>> to create the session and attach it to the request object, and clean
>> it up in request_finished.
>>
>> Looking at the Flask docs, I think you could also write a simple
>> extension. They have a SQLite example at
>> http://flask.pocoo.org/docs/0.12/extensiondev/#the-extension-code,
>> which you ought to be able to adapt for SQLAlchemy. The app context is
>> per-request, so it should be safe
>> (http://flask.pocoo.org/docs/0.12/appcontext/#locality-of-the-context).
>>
>> Hope that helps,
>>
>> Simon
>>
>> On Thu, Feb 15, 2018 at 9:52 AM,  <eugene...@gmail.com> wrote:
>> > Hello, Simon!
>> > So what better way?
>> > Something like this?
>> > SESSION = sessionmaker(bind=engine, autocommit=True)
>> >
>> >
>> >
>> > @decorator_with_args
>> > def session_decorator(func, default=None):
>> >     def wrapper(*a, **kw):
>> >         session = SESSION()
>> >         session.begin(subtransactions=True)
>> >         if 'session' not in kw:
>> >             kw['session'] = session
>> >         try:
>> >             return func(*a, **kw)
>> >         except Exception as e:
>> >             session.rollback()
>> >             logging.error(e)
>> >             return default
>> >         finally:
>> >             if session.is_active:
>> >                 session.commit()
>> >             session.close()
>> >     return wrapper
>> >
>> > I try create additional function
>> >
>> > @session_decorator()
>> > def execute(statement, **kwargs):
>> >     session = kwargs['session']
>> >     fetch = kwargs.get('fetch', 'all')
>> >     result = session.execute(statement)
>> >     if fetch == 'all':
>> >         return result.fetchall()
>> >     elif fetch is False:
>> >         return True
>> >     elif fetch == 'count':
>> >         return result
>> >     return result.fetchone()
>> >
>> > and use it in all execute statements, but that not help.
>> > Still receive error
>> > This result object does not return rows. It has been closed
>> > automatically.
>> > But how it closed if that another session?
>> > Can you correct my code?
>> >
>> >
>> >
>> >
>> > среда, 14 февраля 2018 г., 17:45:59 UTC+3 пользователь Simon King
>> > написал:
>> >>
>> >> I think there are a couple of problems with this.
>> >>
>> >> 1. You are calling scoped_session and sessionmaker every time the
>> >> decorated function is called, which is unnecessary. sessionmaker
>> >> returns a factory function for creating sessions, so you typically
>> >> only have one sessionmaker() call in your application. You could
>> >> either make it a module-global, or do it during application
>> >> configuration.
>> >>
>> >> 2. You are never calling session.close(). This means that the
>> >> transaction started by a web request will stay open after the request
>> >> ends. Since you are using scoped_session as well, the session is
>> >> maintained as a thread-local object, so when the thread handles
>> >> another web request, it will use the same session and the same
>> >> transaction. Your long-running transactions are probably the reason
>> >> why you are getting blocked requests.
>> >>
>> >> You might like to read
>> >>
>> >>
>> >> http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#session-frequently-asked-questions.
>> >>
>> >> I was going to say that you need to add a "finally" section to your
>> >> session_decorator that calls session.close(), but if you ever have one
>> >> decorated function calling another decorated function, they are going
>> >> to interfere with each other. If you are *absolutely certain* that
>> >> will never happen, adding the "finally" section will probably improve
>> >> things, but I would recommend that you try to structure your app a
>> >> little differently, so that the session creation and teardown happen
>> >> at the beginning and end of the web request.
>> >>
>> >> Hope that helps,
>> >>
>> >> Simon
>> >>
>> >>
>> >> On Wed, Feb 14, 2018 at 2:14 PM,  <eugene...@gmail.com> wrote:
>> >> > Decorator like this
>> >> >
>> >> > engine = create_engine(
>> >> >
>> >> >
>> >> >
>> >> > 'mssql+pymssql://{LOGIN}:{PASSWORD}@{HOST}/{DATABASE}?charset={CHARSET}&timeout={TIMEOUT}'.format(**DATABASE),
>> >> >     isolation_level='READ COMMITTED'
>> >> > )
>> >> >
>> >> >
>> >> > def decorator_with_args(decorator_to_enhance):
>> >> >     """
>> >> >     https://habrahabr.ru/post/141501/
>> >> >     """
>> >> >     def decorator_maker(*args, **kwargs):
>> >> >         def decorator_wrapper(func):
>> >> >             return decorator_to_enhance(func, *args, **kwargs)
>> >> >         return decorator_wrapper
>> >> >     return decorator_maker
>> >> >
>> >> >
>> >> > def scope_func():
>> >> >     return scoped_session(sessionmaker(bind=engine,
>> >> > autocommit=True))()
>> >> >
>> >> >
>> >> > @decorator_with_args
>> >> > def session_decorator(func, default=None, **kwargs):
>> >> >     def wrapper(*a, **kw):
>> >> >         session = scope_func()
>> >> >         if 'session' not in kw:
>> >> >             kw['session'] = session
>> >> >         try:
>> >> >             return func(*a, **kw)
>> >> >         except Exception as e:
>> >> >             session.rollback()
>> >> >
>> >> >             print('#####FUNCTION NAME: {}'.format(func.__name__))
>> >> >
>> >> >             print(e)
>> >> >             logging.error(e)
>> >> >             return default
>> >> >     return wrapper
>> >> >
>> >> >
>> >> >
>> >> >
>> >> > среда, 14 февраля 2018 г., 17:06:54 UTC+3 пользователь Simon King
>> >> > написал:
>> >> >>
>> >> >> The pattern you should be aiming for is one in which a fresh
>> >> >> transaction is started for every web request that touches the
>> >> >> database, and that the transaction is closed at the end of the
>> >> >> request. How are you ensuring that at the moment?
>> >> >>
>> >> >> Simon
>> >> >>
>> >> >> On Wed, Feb 14, 2018 at 12:51 PM,  <eugene...@gmail.com> wrote:
>> >> >> > If I run tests where all functions run one-by-one - all tests
>> >> >> > passed.
>> >> >> > But when i run web app and functions can call almost in parallel
>> >> >> > then
>> >> >> > i
>> >> >> > have
>> >> >> > a problem, then there are problems - transactions can block each
>> >> >> > other.
>> >> >> > I tried to set the isolation level of SNAPSHOT and READ COMMITTED,
>> >> >> > but
>> >> >> > it
>> >> >> > did not help.
>> >> >> >
>> >> >> > среда, 14 февраля 2018 г., 14:58:37 UTC+3 пользователь
>> >> >> > eugene...@gmail.com
>> >> >> > написал:
>> >> >> >>
>> >> >> >> Hello, Mike!
>> >> >> >> In my web app i have many selects like
>> >> >> >> session.execute(select([table1]).where(condition))
>> >> >> >> and not so much updates, inserts and deletes like
>> >> >> >> session.execute(update(table1).where(condition).values(**values))
>> >> >> >> session.execute(insert(table1).values(**values))
>> >> >> >> session.execute(delete(table1).where(condition))
>> >> >> >>
>> >> >> >> What better way to create session for web application?
>> >> >> >> Without additional components like flask-sqlalchemy.
>> >> >> >>
>> >> >> >> суббота, 27 января 2018 г., 20:23:05 UTC+3 пользователь Mike
>> >> >> >> Bayer
>> >> >> >> написал:
>> >> >> >>>
>> >> >> >>> On Sat, Jan 27, 2018 at 5:49 AM, Евгений Рымарев
>> >> >> >>> <rymarev...@gmail.com> wrote:
>> >> >> >>> > I receive this error:
>> >> >> >>> > This result object does not return rows. It has been closed
>> >> >> >>> > automatically.
>> >> >> >>>
>> >> >> >>> there's a lot of weird situations which can cause that error,
>> >> >> >>> usually
>> >> >> >>> when using a connection that has had some failure condition
>> >> >> >>> occur
>> >> >> >>> upon
>> >> >> >>> it which renders the connection unusable until either a
>> >> >> >>> transaction
>> >> >> >>> is
>> >> >> >>> rolled back or sometimes the connection needs to be discarded.
>> >> >> >>> We
>> >> >> >>> can't diagnose it without a full example that reproduces it as
>> >> >> >>> well
>> >> >> >>> as
>> >> >> >>> the complete stack trace.
>> >> >> >>>
>> >> >> >>>
>> >> >> >>> >
>> >> >> >>> >
>> >> >> >>> >
>> >> >> >>> > суббота, 27 января 2018 г., 1:09:53 UTC+3 пользователь Mike
>> >> >> >>> > Bayer
>> >> >> >>> > написал:
>> >> >> >>> >>
>> >> >> >>> >> On Fri, Jan 26, 2018 at 4:21 PM, Евгений Рымарев
>> >> >> >>> >> <rymarev...@gmail.com> wrote:
>> >> >> >>> >> > Hello, everyone!
>> >> >> >>> >> > Engine:
>> >> >> >>> >> > engine = create_engine(
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> > 'mssql+pymssql://{LOGIN}:{PASSWORD}@{HOST}/{DATABASE}?charset={CHARSET}'.format(**DATABASE),
>> >> >> >>> >> >     isolation_level='READ COMMITTED'
>> >> >> >>> >> > )
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> > My first decorator for session:
>> >> >> >>> >> > @decorator_with_args
>> >> >> >>> >> > def session_decorator(func, default=None):
>> >> >> >>> >> >    def wrapper(*a, **kw):
>> >> >> >>> >> >        s = Session(engine)
>> >> >> >>> >> >        kw['session'] = s
>> >> >> >>> >> >        try:
>> >> >> >>> >> >            return func(*a, **kw)
>> >> >> >>> >> >        except Exception as e:
>> >> >> >>> >> >            func(*a, **kw)
>> >> >> >>> >> >            s.rollback()
>> >> >> >>> >> >            s.close()
>> >> >> >>> >> >            logging.error(e)
>> >> >> >>> >> >            return default
>> >> >> >>> >> >        finally:
>> >> >> >>> >> >            s.commit()
>> >> >> >>> >> >            s.close()
>> >> >> >>> >> >    return wrapper
>> >> >> >>> >> >
>> >> >> >>> >> > My second decorator for session:
>> >> >> >>> >> > session = scoped_session(sessionmaker(bind=engine))
>> >> >> >>> >> >
>> >> >> >>> >> >
>> >> >> >>> >> > @decorator_with_args
>> >> >> >>> >> > def session_decorator(func, default=None):
>> >> >> >>> >> >    def wrapper(*a, **kw):
>> >> >> >>> >> >        kw['session'] = session
>> >> >> >>> >> >        try:
>> >> >> >>> >> >            return func(*a, **kw)
>> >> >> >>> >> >        except Exception as e:
>> >> >> >>> >> >            session.remove()
>> >> >> >>> >> >            logging.error(e)
>> >> >> >>> >> >            return default
>> >> >> >>> >> >        finally:
>> >> >> >>> >> >            session.remove()
>> >> >> >>> >> >    return wrapper
>> >> >> >>> >> >
>> >> >> >>> >> > In both attempts, I came to the conclusion that sessions
>> >> >> >>> >> > can
>> >> >> >>> >> > block
>> >> >> >>> >> > other
>> >> >> >>> >> > sessions.
>> >> >> >>> >> > How correctly to create a session once, so that it can be
>> >> >> >>> >> > used
>> >> >> >>> >> > throughout
>> >> >> >>> >> > the web application and no locks were created?
>> >> >> >>> >>
>> >> >> >>> >> The Session doesn't create locks, transactions and your
>> >> >> >>> >> database
>> >> >> >>> >> does.
>> >> >> >>> >>
>> >> >> >>> >> What is the nature of these "blocks", are they deadlocks
>> >> >> >>> >> between
>> >> >> >>> >> tables or rows?  What operations are prevented from
>> >> >> >>> >> proceeding?
>> >> >> >>> >> Are
>> >> >> >>> >> the locks timing out?   SQL Server has graphical consoles
>> >> >> >>> >> that
>> >> >> >>> >> can
>> >> >> >>> >> show you this.
>> >> >> >>> >>
>> >> >> >>> >> What version of SQL Server is this?   Do you have
>> >> >> >>> >> ALLOW_SNAPSHOT_ISOLATION and READ_COMMITTED_SNAPSHOT turned
>> >> >> >>> >> on?
>> >> >> >>> >>
>> >> >> >>> >>
>> >> >> >>> >> >
>> >> >> >>> >> > --
>> >> >> >>> >> > SQLAlchemy -
>> >> >> >>> >> > The Python SQL Toolkit and Object Relational Mapper
>> >> >> >>> >> >
>> >> >> >>> >> > http://www.sqlalchemy.org/
>> >> >> >>> >> >
>> >> >> >>> >> > To post example code, please provide an MCVE: Minimal,
>> >> >> >>> >> > Complete,
>> >> >> >>> >> > and
>> >> >> >>> >> > Verifiable Example. See http://stackoverflow.com/help/mcve
>> >> >> >>> >> > for
>> >> >> >>> >> > a
>> >> >> >>> >> > full
>> >> >> >>> >> > description.
>> >> >> >>> >> > ---
>> >> >> >>> >> > You received this message because you are subscribed to the
>> >> >> >>> >> > Google
>> >> >> >>> >> > Groups
>> >> >> >>> >> > "sqlalchemy" group.
>> >> >> >>> >> > To unsubscribe from this group and stop receiving emails
>> >> >> >>> >> > from
>> >> >> >>> >> > it,
>> >> >> >>> >> > send
>> >> >> >>> >> > an
>> >> >> >>> >> > email to sqlalchemy+...@googlegroups.com.
>> >> >> >>> >> > To post to this group, send email to
>> >> >> >>> >> > sqlal...@googlegroups.com.
>> >> >> >>> >> > Visit this group at
>> >> >> >>> >> > https://groups.google.com/group/sqlalchemy.
>> >> >> >>> >> > For more options, visit https://groups.google.com/d/optout.
>> >> >> >>> >
>> >> >> >>> > --
>> >> >> >>> > SQLAlchemy -
>> >> >> >>> > The Python SQL Toolkit and Object Relational Mapper
>> >> >> >>> >
>> >> >> >>> > http://www.sqlalchemy.org/
>> >> >> >>> >
>> >> >> >>> > To post example code, please provide an MCVE: Minimal,
>> >> >> >>> > Complete,
>> >> >> >>> > and
>> >> >> >>> > Verifiable Example. See http://stackoverflow.com/help/mcve for
>> >> >> >>> > a
>> >> >> >>> > full
>> >> >> >>> > description.
>> >> >> >>> > ---
>> >> >> >>> > You received this message because you are subscribed to the
>> >> >> >>> > Google
>> >> >> >>> > Groups
>> >> >> >>> > "sqlalchemy" group.
>> >> >> >>> > To unsubscribe from this group and stop receiving emails from
>> >> >> >>> > it,
>> >> >> >>> > send
>> >> >> >>> > an
>> >> >> >>> > email to sqlalchemy+...@googlegroups.com.
>> >> >> >>> > To post to this group, send email to
>> >> >> >>> > sqlal...@googlegroups.com.
>> >> >> >>> > Visit this group at
>> >> >> >>> > https://groups.google.com/group/sqlalchemy.
>> >> >> >>> > For more options, visit https://groups.google.com/d/optout.
>> >> >> >
>> >> >> > --
>> >> >> > SQLAlchemy -
>> >> >> > The Python SQL Toolkit and Object Relational Mapper
>> >> >> >
>> >> >> > http://www.sqlalchemy.org/
>> >> >> >
>> >> >> > To post example code, please provide an MCVE: Minimal, Complete,
>> >> >> > and
>> >> >> > Verifiable Example. See http://stackoverflow.com/help/mcve for a
>> >> >> > full
>> >> >> > description.
>> >> >> > ---
>> >> >> > You received this message because you are subscribed to the Google
>> >> >> > Groups
>> >> >> > "sqlalchemy" group.
>> >> >> > To unsubscribe from this group and stop receiving emails from it,
>> >> >> > send
>> >> >> > an
>> >> >> > email to sqlalchemy+...@googlegroups.com.
>> >> >> > To post to this group, send email to sqlal...@googlegroups.com.
>> >> >> > Visit this group at https://groups.google.com/group/sqlalchemy.
>> >> >> > For more options, visit https://groups.google.com/d/optout.
>> >> >
>> >> > --
>> >> > SQLAlchemy -
>> >> > The Python SQL Toolkit and Object Relational Mapper
>> >> >
>> >> > http://www.sqlalchemy.org/
>> >> >
>> >> > To post example code, please provide an MCVE: Minimal, Complete, and
>> >> > Verifiable Example. See http://stackoverflow.com/help/mcve for a full
>> >> > description.
>> >> > ---
>> >> > You received this message because you are subscribed to the Google
>> >> > Groups
>> >> > "sqlalchemy" group.
>> >> > To unsubscribe from this group and stop receiving emails from it,
>> >> > send
>> >> > an
>> >> > email to sqlalchemy+...@googlegroups.com.
>> >> > To post to this group, send email to sqlal...@googlegroups.com.
>> >> > Visit this group at https://groups.google.com/group/sqlalchemy.
>> >> > For more options, visit https://groups.google.com/d/optout.
>> >
>> > --
>> > SQLAlchemy -
>> > The Python SQL Toolkit and Object Relational Mapper
>> >
>> > http://www.sqlalchemy.org/
>> >
>> > To post example code, please provide an MCVE: Minimal, Complete, and
>> > Verifiable Example. See http://stackoverflow.com/help/mcve for a full
>> > description.
>> > ---
>> > You received this message because you are subscribed to the Google
>> > Groups
>> > "sqlalchemy" group.
>> > To unsubscribe from this group and stop receiving emails from it, send
>> > an
>> > email to sqlalchemy+...@googlegroups.com.
>> > To post to this group, send email to sqlal...@googlegroups.com.
>> > Visit this group at https://groups.google.com/group/sqlalchemy.
>> > For more options, visit https://groups.google.com/d/optout.
>
> --
> SQLAlchemy -
> The Python SQL Toolkit and Object Relational Mapper
>
> http://www.sqlalchemy.org/
>
> To post example code, please provide an MCVE: Minimal, Complete, and
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
> description.
> ---
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlalchemy@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to