Flask-Sqlalchemy autocommit UPDATE while insert multiple instances?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







0















I try to save some columns (eg: tags, models) with JSON encoded string.



And I hope to always keep then decoded in use.



I have read some refers to add configs to disable autocommit and autoflush , but it doesn't work.



While the instance was added into db.session and then changed value , orm still try to commit an UPDATE OPERATION and then raise TypeError.



Here is my code.



```python



import json
from sqlalchemy import orm
from flask_sqlalchemy import SQLAlchemy

session_options = dict(
bind=None,
autoflush=False,
autocommit=False,
expire_on_commit=False,
)
db = SQLAlchemy(session_options=session_options)


class Sample(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# tags, models : string of json.dumps(array)
tags = db.Column(db.String(128), default='')
models = db.Column(db.String(128), default='')

def __init__(self, **kwargs):
cls = self.__class__
super(cls, self).__init__(**kwargs)
self.formatting()

@orm.reconstructor
def init_on_load(self):
self.formatting()

def formatting(self):
self.tags = json.loads(self.tags)
self.models = json.loads(self.models)

def save(self):
self.tags = json.dumps(self.tags)
self.models = json.dumps(self.models)

db.session.add(self)
db.session.commit()

self.formatting()
## fixme !!!
## formatting after saved will cause auto-commit and raise TypeError


```



Thank you :)



ps: Flask-SQLAlchemy==2.3.2










share|improve this question

























  • Hi, please include the full trace back of the error.

    – SuperShoot
    Nov 24 '18 at 10:58











  • Thank you very much. Finally I found it raise error because I lack of "db.session.close()" after "db.session.commit()" . But I am still confused , because I was told that the db.session.close() is automatically called in db.session.commit()

    – NicoNing
    Nov 25 '18 at 1:26











  • I am trying to explain the error in the answer. It is a really stupid error.

    – NicoNing
    Nov 25 '18 at 1:27


















0















I try to save some columns (eg: tags, models) with JSON encoded string.



And I hope to always keep then decoded in use.



I have read some refers to add configs to disable autocommit and autoflush , but it doesn't work.



While the instance was added into db.session and then changed value , orm still try to commit an UPDATE OPERATION and then raise TypeError.



Here is my code.



```python



import json
from sqlalchemy import orm
from flask_sqlalchemy import SQLAlchemy

session_options = dict(
bind=None,
autoflush=False,
autocommit=False,
expire_on_commit=False,
)
db = SQLAlchemy(session_options=session_options)


class Sample(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# tags, models : string of json.dumps(array)
tags = db.Column(db.String(128), default='')
models = db.Column(db.String(128), default='')

def __init__(self, **kwargs):
cls = self.__class__
super(cls, self).__init__(**kwargs)
self.formatting()

@orm.reconstructor
def init_on_load(self):
self.formatting()

def formatting(self):
self.tags = json.loads(self.tags)
self.models = json.loads(self.models)

def save(self):
self.tags = json.dumps(self.tags)
self.models = json.dumps(self.models)

db.session.add(self)
db.session.commit()

self.formatting()
## fixme !!!
## formatting after saved will cause auto-commit and raise TypeError


```



Thank you :)



ps: Flask-SQLAlchemy==2.3.2










share|improve this question

























  • Hi, please include the full trace back of the error.

    – SuperShoot
    Nov 24 '18 at 10:58











  • Thank you very much. Finally I found it raise error because I lack of "db.session.close()" after "db.session.commit()" . But I am still confused , because I was told that the db.session.close() is automatically called in db.session.commit()

    – NicoNing
    Nov 25 '18 at 1:26











  • I am trying to explain the error in the answer. It is a really stupid error.

    – NicoNing
    Nov 25 '18 at 1:27














0












0








0


1






I try to save some columns (eg: tags, models) with JSON encoded string.



And I hope to always keep then decoded in use.



I have read some refers to add configs to disable autocommit and autoflush , but it doesn't work.



While the instance was added into db.session and then changed value , orm still try to commit an UPDATE OPERATION and then raise TypeError.



Here is my code.



```python



import json
from sqlalchemy import orm
from flask_sqlalchemy import SQLAlchemy

session_options = dict(
bind=None,
autoflush=False,
autocommit=False,
expire_on_commit=False,
)
db = SQLAlchemy(session_options=session_options)


class Sample(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# tags, models : string of json.dumps(array)
tags = db.Column(db.String(128), default='')
models = db.Column(db.String(128), default='')

def __init__(self, **kwargs):
cls = self.__class__
super(cls, self).__init__(**kwargs)
self.formatting()

@orm.reconstructor
def init_on_load(self):
self.formatting()

def formatting(self):
self.tags = json.loads(self.tags)
self.models = json.loads(self.models)

def save(self):
self.tags = json.dumps(self.tags)
self.models = json.dumps(self.models)

db.session.add(self)
db.session.commit()

self.formatting()
## fixme !!!
## formatting after saved will cause auto-commit and raise TypeError


```



Thank you :)



ps: Flask-SQLAlchemy==2.3.2










share|improve this question
















I try to save some columns (eg: tags, models) with JSON encoded string.



And I hope to always keep then decoded in use.



I have read some refers to add configs to disable autocommit and autoflush , but it doesn't work.



While the instance was added into db.session and then changed value , orm still try to commit an UPDATE OPERATION and then raise TypeError.



Here is my code.



```python



import json
from sqlalchemy import orm
from flask_sqlalchemy import SQLAlchemy

session_options = dict(
bind=None,
autoflush=False,
autocommit=False,
expire_on_commit=False,
)
db = SQLAlchemy(session_options=session_options)


class Sample(db.Model):
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
# tags, models : string of json.dumps(array)
tags = db.Column(db.String(128), default='')
models = db.Column(db.String(128), default='')

def __init__(self, **kwargs):
cls = self.__class__
super(cls, self).__init__(**kwargs)
self.formatting()

@orm.reconstructor
def init_on_load(self):
self.formatting()

def formatting(self):
self.tags = json.loads(self.tags)
self.models = json.loads(self.models)

def save(self):
self.tags = json.dumps(self.tags)
self.models = json.dumps(self.models)

db.session.add(self)
db.session.commit()

self.formatting()
## fixme !!!
## formatting after saved will cause auto-commit and raise TypeError


```



Thank you :)



ps: Flask-SQLAlchemy==2.3.2







python python-3.x flask sqlalchemy flask-sqlalchemy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 2:33







NicoNing

















asked Nov 24 '18 at 7:02









NicoNingNicoNing

34




34













  • Hi, please include the full trace back of the error.

    – SuperShoot
    Nov 24 '18 at 10:58











  • Thank you very much. Finally I found it raise error because I lack of "db.session.close()" after "db.session.commit()" . But I am still confused , because I was told that the db.session.close() is automatically called in db.session.commit()

    – NicoNing
    Nov 25 '18 at 1:26











  • I am trying to explain the error in the answer. It is a really stupid error.

    – NicoNing
    Nov 25 '18 at 1:27



















  • Hi, please include the full trace back of the error.

    – SuperShoot
    Nov 24 '18 at 10:58











  • Thank you very much. Finally I found it raise error because I lack of "db.session.close()" after "db.session.commit()" . But I am still confused , because I was told that the db.session.close() is automatically called in db.session.commit()

    – NicoNing
    Nov 25 '18 at 1:26











  • I am trying to explain the error in the answer. It is a really stupid error.

    – NicoNing
    Nov 25 '18 at 1:27

















Hi, please include the full trace back of the error.

– SuperShoot
Nov 24 '18 at 10:58





Hi, please include the full trace back of the error.

– SuperShoot
Nov 24 '18 at 10:58













Thank you very much. Finally I found it raise error because I lack of "db.session.close()" after "db.session.commit()" . But I am still confused , because I was told that the db.session.close() is automatically called in db.session.commit()

– NicoNing
Nov 25 '18 at 1:26





Thank you very much. Finally I found it raise error because I lack of "db.session.close()" after "db.session.commit()" . But I am still confused , because I was told that the db.session.close() is automatically called in db.session.commit()

– NicoNing
Nov 25 '18 at 1:26













I am trying to explain the error in the answer. It is a really stupid error.

– NicoNing
Nov 25 '18 at 1:27





I am trying to explain the error in the answer. It is a really stupid error.

– NicoNing
Nov 25 '18 at 1:27












1 Answer
1






active

oldest

votes


















0














This error was raised by lacking called db.session.close() after db.session.commit()



I was told that db.session.close() is automatically called in db.session.commit(). And the real has denied my cognition.



And I try to refer the source code of sqlalchmey, and then I find the db.session is an instance of sqlalchemy.orm.scoping.scoped_session, NOT sqlalchemy.orm.SessionTransaction.



Here is the source code in sqlalchemy.orm.SessionTransaction



```python



def commit(self):
self._assert_active(prepared_ok=True)
if self._state is not PREPARED:
self._prepare_impl()

if self._parent is None or self.nested:
for t in set(self._connections.values()):
t[1].commit()

self._state = COMMITTED
self.session.dispatch.after_commit(self.session)

if self.session._enable_transaction_accounting:
self._remove_snapshot()

self.close()
return self._parent


```



It’s really confusing.






If you want to repeat this Error, here is Test code:



```python



"""
# snippet for testing <class:Sample>
"""

from flask import Flask
app = Flask(__name__)
app.config.from_mapping(
SQLALCHEMY_ECHO=True,
SQLALCHEMY_TRACK_MODIFICATIONS=False,
SQLALCHEMY_DATABASE_URI='sqlite:///test_orm.sqlite.db',
)

db.init_app(app=app)
db.app = app
db.create_all()

d1 = dict(
tags='["python2","flask"]',
models='["m1"]'
)
m1 = Sample(**d1)
print(1111, type(m1.tags), m1.tags)
m1.save()
print(1112, type(m1.tags), m1.tags)
dm1 = Sample.query.filter(Sample.id == m1.id).all()[0]
print(1113, dm1, type(dm1.tags), dm1.tags)

## fixme[Q1] !!!
## if not continue with $d2, it won't raise error of UPDATE $d1

d2 = dict(
tags='["python3","flask"]',
models='["m2", "m3"]'
)
m2 = Sample(**d2)
print(2221, type(m2.tags), m2.tags)

## fixme[Q1] !!!
# db.session.close()
## If session was not closed, error raise here.

m2.save()
print(2222, type(m2.tags), m2.tags)
dm2 = Sample.query.filter(Sample.id == m2.id).all()[0]
print(2223, dm2, type(dm2.tags), dm2.tags)


```



Thank you for your read ,wish to disabuse your same confusion.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53455952%2fflask-sqlalchemy-autocommit-update-while-insert-multiple-instances%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    This error was raised by lacking called db.session.close() after db.session.commit()



    I was told that db.session.close() is automatically called in db.session.commit(). And the real has denied my cognition.



    And I try to refer the source code of sqlalchmey, and then I find the db.session is an instance of sqlalchemy.orm.scoping.scoped_session, NOT sqlalchemy.orm.SessionTransaction.



    Here is the source code in sqlalchemy.orm.SessionTransaction



    ```python



    def commit(self):
    self._assert_active(prepared_ok=True)
    if self._state is not PREPARED:
    self._prepare_impl()

    if self._parent is None or self.nested:
    for t in set(self._connections.values()):
    t[1].commit()

    self._state = COMMITTED
    self.session.dispatch.after_commit(self.session)

    if self.session._enable_transaction_accounting:
    self._remove_snapshot()

    self.close()
    return self._parent


    ```



    It’s really confusing.






    If you want to repeat this Error, here is Test code:



    ```python



    """
    # snippet for testing <class:Sample>
    """

    from flask import Flask
    app = Flask(__name__)
    app.config.from_mapping(
    SQLALCHEMY_ECHO=True,
    SQLALCHEMY_TRACK_MODIFICATIONS=False,
    SQLALCHEMY_DATABASE_URI='sqlite:///test_orm.sqlite.db',
    )

    db.init_app(app=app)
    db.app = app
    db.create_all()

    d1 = dict(
    tags='["python2","flask"]',
    models='["m1"]'
    )
    m1 = Sample(**d1)
    print(1111, type(m1.tags), m1.tags)
    m1.save()
    print(1112, type(m1.tags), m1.tags)
    dm1 = Sample.query.filter(Sample.id == m1.id).all()[0]
    print(1113, dm1, type(dm1.tags), dm1.tags)

    ## fixme[Q1] !!!
    ## if not continue with $d2, it won't raise error of UPDATE $d1

    d2 = dict(
    tags='["python3","flask"]',
    models='["m2", "m3"]'
    )
    m2 = Sample(**d2)
    print(2221, type(m2.tags), m2.tags)

    ## fixme[Q1] !!!
    # db.session.close()
    ## If session was not closed, error raise here.

    m2.save()
    print(2222, type(m2.tags), m2.tags)
    dm2 = Sample.query.filter(Sample.id == m2.id).all()[0]
    print(2223, dm2, type(dm2.tags), dm2.tags)


    ```



    Thank you for your read ,wish to disabuse your same confusion.






    share|improve this answer




























      0














      This error was raised by lacking called db.session.close() after db.session.commit()



      I was told that db.session.close() is automatically called in db.session.commit(). And the real has denied my cognition.



      And I try to refer the source code of sqlalchmey, and then I find the db.session is an instance of sqlalchemy.orm.scoping.scoped_session, NOT sqlalchemy.orm.SessionTransaction.



      Here is the source code in sqlalchemy.orm.SessionTransaction



      ```python



      def commit(self):
      self._assert_active(prepared_ok=True)
      if self._state is not PREPARED:
      self._prepare_impl()

      if self._parent is None or self.nested:
      for t in set(self._connections.values()):
      t[1].commit()

      self._state = COMMITTED
      self.session.dispatch.after_commit(self.session)

      if self.session._enable_transaction_accounting:
      self._remove_snapshot()

      self.close()
      return self._parent


      ```



      It’s really confusing.






      If you want to repeat this Error, here is Test code:



      ```python



      """
      # snippet for testing <class:Sample>
      """

      from flask import Flask
      app = Flask(__name__)
      app.config.from_mapping(
      SQLALCHEMY_ECHO=True,
      SQLALCHEMY_TRACK_MODIFICATIONS=False,
      SQLALCHEMY_DATABASE_URI='sqlite:///test_orm.sqlite.db',
      )

      db.init_app(app=app)
      db.app = app
      db.create_all()

      d1 = dict(
      tags='["python2","flask"]',
      models='["m1"]'
      )
      m1 = Sample(**d1)
      print(1111, type(m1.tags), m1.tags)
      m1.save()
      print(1112, type(m1.tags), m1.tags)
      dm1 = Sample.query.filter(Sample.id == m1.id).all()[0]
      print(1113, dm1, type(dm1.tags), dm1.tags)

      ## fixme[Q1] !!!
      ## if not continue with $d2, it won't raise error of UPDATE $d1

      d2 = dict(
      tags='["python3","flask"]',
      models='["m2", "m3"]'
      )
      m2 = Sample(**d2)
      print(2221, type(m2.tags), m2.tags)

      ## fixme[Q1] !!!
      # db.session.close()
      ## If session was not closed, error raise here.

      m2.save()
      print(2222, type(m2.tags), m2.tags)
      dm2 = Sample.query.filter(Sample.id == m2.id).all()[0]
      print(2223, dm2, type(dm2.tags), dm2.tags)


      ```



      Thank you for your read ,wish to disabuse your same confusion.






      share|improve this answer


























        0












        0








        0







        This error was raised by lacking called db.session.close() after db.session.commit()



        I was told that db.session.close() is automatically called in db.session.commit(). And the real has denied my cognition.



        And I try to refer the source code of sqlalchmey, and then I find the db.session is an instance of sqlalchemy.orm.scoping.scoped_session, NOT sqlalchemy.orm.SessionTransaction.



        Here is the source code in sqlalchemy.orm.SessionTransaction



        ```python



        def commit(self):
        self._assert_active(prepared_ok=True)
        if self._state is not PREPARED:
        self._prepare_impl()

        if self._parent is None or self.nested:
        for t in set(self._connections.values()):
        t[1].commit()

        self._state = COMMITTED
        self.session.dispatch.after_commit(self.session)

        if self.session._enable_transaction_accounting:
        self._remove_snapshot()

        self.close()
        return self._parent


        ```



        It’s really confusing.






        If you want to repeat this Error, here is Test code:



        ```python



        """
        # snippet for testing <class:Sample>
        """

        from flask import Flask
        app = Flask(__name__)
        app.config.from_mapping(
        SQLALCHEMY_ECHO=True,
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        SQLALCHEMY_DATABASE_URI='sqlite:///test_orm.sqlite.db',
        )

        db.init_app(app=app)
        db.app = app
        db.create_all()

        d1 = dict(
        tags='["python2","flask"]',
        models='["m1"]'
        )
        m1 = Sample(**d1)
        print(1111, type(m1.tags), m1.tags)
        m1.save()
        print(1112, type(m1.tags), m1.tags)
        dm1 = Sample.query.filter(Sample.id == m1.id).all()[0]
        print(1113, dm1, type(dm1.tags), dm1.tags)

        ## fixme[Q1] !!!
        ## if not continue with $d2, it won't raise error of UPDATE $d1

        d2 = dict(
        tags='["python3","flask"]',
        models='["m2", "m3"]'
        )
        m2 = Sample(**d2)
        print(2221, type(m2.tags), m2.tags)

        ## fixme[Q1] !!!
        # db.session.close()
        ## If session was not closed, error raise here.

        m2.save()
        print(2222, type(m2.tags), m2.tags)
        dm2 = Sample.query.filter(Sample.id == m2.id).all()[0]
        print(2223, dm2, type(dm2.tags), dm2.tags)


        ```



        Thank you for your read ,wish to disabuse your same confusion.






        share|improve this answer













        This error was raised by lacking called db.session.close() after db.session.commit()



        I was told that db.session.close() is automatically called in db.session.commit(). And the real has denied my cognition.



        And I try to refer the source code of sqlalchmey, and then I find the db.session is an instance of sqlalchemy.orm.scoping.scoped_session, NOT sqlalchemy.orm.SessionTransaction.



        Here is the source code in sqlalchemy.orm.SessionTransaction



        ```python



        def commit(self):
        self._assert_active(prepared_ok=True)
        if self._state is not PREPARED:
        self._prepare_impl()

        if self._parent is None or self.nested:
        for t in set(self._connections.values()):
        t[1].commit()

        self._state = COMMITTED
        self.session.dispatch.after_commit(self.session)

        if self.session._enable_transaction_accounting:
        self._remove_snapshot()

        self.close()
        return self._parent


        ```



        It’s really confusing.






        If you want to repeat this Error, here is Test code:



        ```python



        """
        # snippet for testing <class:Sample>
        """

        from flask import Flask
        app = Flask(__name__)
        app.config.from_mapping(
        SQLALCHEMY_ECHO=True,
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        SQLALCHEMY_DATABASE_URI='sqlite:///test_orm.sqlite.db',
        )

        db.init_app(app=app)
        db.app = app
        db.create_all()

        d1 = dict(
        tags='["python2","flask"]',
        models='["m1"]'
        )
        m1 = Sample(**d1)
        print(1111, type(m1.tags), m1.tags)
        m1.save()
        print(1112, type(m1.tags), m1.tags)
        dm1 = Sample.query.filter(Sample.id == m1.id).all()[0]
        print(1113, dm1, type(dm1.tags), dm1.tags)

        ## fixme[Q1] !!!
        ## if not continue with $d2, it won't raise error of UPDATE $d1

        d2 = dict(
        tags='["python3","flask"]',
        models='["m2", "m3"]'
        )
        m2 = Sample(**d2)
        print(2221, type(m2.tags), m2.tags)

        ## fixme[Q1] !!!
        # db.session.close()
        ## If session was not closed, error raise here.

        m2.save()
        print(2222, type(m2.tags), m2.tags)
        dm2 = Sample.query.filter(Sample.id == m2.id).all()[0]
        print(2223, dm2, type(dm2.tags), dm2.tags)


        ```



        Thank you for your read ,wish to disabuse your same confusion.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 25 '18 at 2:15









        NicoNingNicoNing

        34




        34
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53455952%2fflask-sqlalchemy-autocommit-update-while-insert-multiple-instances%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()