question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Postgres error "SAVEPOINT can only be used in transaction blocks" when used with live_server

See original GitHub issue

I have tests, that I would like to run with live_server from pytest-flask package.

I thought it works ok, but only for single request. Full repo with working example, failing test

Here are some pieces of the code:

# models.py
class Category(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String, unique=True, nullable=False)

# view
@blog.route('/categories')
def list_categories():
    return '<br/>'.join(str(x.id) + ': ' + x.name for x in models.Category.query)

factories from conftest.py

@pytest.fixture(scope='function')
def base_factory(db_session):
    class BaseFactory(factory.alchemy.SQLAlchemyModelFactory):
        class Meta:
            abstract = True
            sqlalchemy_session = db_session
            sqlalchemy_session_persistence = 'flush'
    return BaseFactory

@pytest.fixture(scope='function')
def category_factory(base_factory):
    class CategoryFactory(base_factory):
        class Meta:
            model = models.Category
        name = factory.Sequence(lambda n: u'Category %d' % n)
    return CategoryFactory

Test itself:

from flask import url_for
import requests

from demo_app import models

def test_list_categories(live_server, category_factory):
    categories = category_factory.create_batch(5)

    assert models.Category.query.count() == 5

    url = url_for('blog.list_categories', _external=True)

    response_1 = requests.get(url)

    assert response_1.status_code == 200
    data_1 = response_1.content.decode('utf-8')
    for category in categories:
        assert category.name in data_1

    assert models.Category.query.count() == 5

    response_2 = requests.get(url)

    assert response_2.status_code == 200
    data_2 = response_2.content.decode('utf-8')
    print(data_2)
    for category in categories:
        assert category.name in data_2

I’m getting error on line assert models.Category.query.count() == 5, or if I comment it out, data_2 data returned by the server is empty.

The error:

self = <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x104135780>
cursor = <cursor object at 0x1040ea900; closed: -1>
statement = 'SAVEPOINT sa_savepoint_23', parameters = {}
context = <sqlalchemy.dialects.postgresql.psycopg2.PGExecutionContext_psycopg2 object at 0x104321048>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       sqlalchemy.exc.InternalError: (psycopg2.errors.NoActiveSqlTransaction) SAVEPOINT can only be used in transaction blocks
E       
E       [SQL: SAVEPOINT sa_savepoint_23]
E       (Background on this error at: http://sqlalche.me/e/2j85)

Full stack trace

Could you please help me, I don’t know where to start to investigate this.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:2
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jeancochranecommented, Sep 6, 2019

Awesome, thanks @citizen-stig! I’ll have time to do some testing this weekend.

0reactions
citizen-stigcommented, Sep 3, 2019

@jeancochrane , I’ve finally managed to create docker environment, repository is updated: https://github.com/citizen-stig/flask-pytest-samples

just use docker-compose up and error will be printed in console

Read more comments on GitHub >

github_iconTop Results From Across the Web

Knex migration fails with - SAVEPOINT can only be used in ...
Knex creates implicitly transaction for your migration, so that might have something to do with savepoint error (nested transactions are ...
Read more >
Documentation: 15: SAVEPOINT - PostgreSQL
Savepoints can only be established when inside a transaction block. There can be multiple savepoints defined within a transaction.
Read more >
Bug report #17535: Postgresql: empty SAVEPOINTS
In particular, an error related to SAVEPOINT happens some times upon modifications on layers. ERROR: SAVEPOINT can only be used in transaction blocks....
Read more >
Postgres error "SAVEPOINT can only be used in transaction ...
Postgres error "SAVEPOINT can only be used in transaction blocks" when used with live_server.
Read more >
RELEASE SAVEPOINT can only be used in transaction blocks ...
Anyone that can assist with the following logged errors i have? I need an explanation as to what could cause such errors.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found