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;
}
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
add a comment |
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
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
add a comment |
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
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
python python-3.x flask sqlalchemy flask-sqlalchemy
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 25 '18 at 2:15
NicoNingNicoNing
34
34
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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