SQLAlchemy can't set attribute error when updating value












1















I have a table mailtable in a backend PostgreSQL database and I'm querying it using SQLAlchemy ORM using a given mailId. For the following code, the amEngine is already set up. When it gets to the mailRow.usercomment = 'Hello World' line, it throws:




AttributeError: can't set attribute




Base = declarative_base()
Base.metadata.reflect(amEngine)
metaAm = MetaData()
metaAm.reflect(bind=amEngine)
mt = metaAm.tables['mailtable']
Session = sessionmaker(bind=amEngine)
amSession = Session()
mailRow = amSession.query(
mt
).filter(
mt.c.id == mailId
).first()
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
amSession.flush()
amSession.commit()


I need to read the address column (successful) and update the usercomment column (throws exception). The PostgreSQL type for both columns is text.
How can I do this? I'm sure this must be a very simple issue, but for the life of me I cannot see the problem.



Many thanks.










share|improve this question

























  • Related: stackoverflow.com/questions/51391039/…

    – SuperShoot
    Nov 27 '18 at 4:21
















1















I have a table mailtable in a backend PostgreSQL database and I'm querying it using SQLAlchemy ORM using a given mailId. For the following code, the amEngine is already set up. When it gets to the mailRow.usercomment = 'Hello World' line, it throws:




AttributeError: can't set attribute




Base = declarative_base()
Base.metadata.reflect(amEngine)
metaAm = MetaData()
metaAm.reflect(bind=amEngine)
mt = metaAm.tables['mailtable']
Session = sessionmaker(bind=amEngine)
amSession = Session()
mailRow = amSession.query(
mt
).filter(
mt.c.id == mailId
).first()
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
amSession.flush()
amSession.commit()


I need to read the address column (successful) and update the usercomment column (throws exception). The PostgreSQL type for both columns is text.
How can I do this? I'm sure this must be a very simple issue, but for the life of me I cannot see the problem.



Many thanks.










share|improve this question

























  • Related: stackoverflow.com/questions/51391039/…

    – SuperShoot
    Nov 27 '18 at 4:21














1












1








1








I have a table mailtable in a backend PostgreSQL database and I'm querying it using SQLAlchemy ORM using a given mailId. For the following code, the amEngine is already set up. When it gets to the mailRow.usercomment = 'Hello World' line, it throws:




AttributeError: can't set attribute




Base = declarative_base()
Base.metadata.reflect(amEngine)
metaAm = MetaData()
metaAm.reflect(bind=amEngine)
mt = metaAm.tables['mailtable']
Session = sessionmaker(bind=amEngine)
amSession = Session()
mailRow = amSession.query(
mt
).filter(
mt.c.id == mailId
).first()
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
amSession.flush()
amSession.commit()


I need to read the address column (successful) and update the usercomment column (throws exception). The PostgreSQL type for both columns is text.
How can I do this? I'm sure this must be a very simple issue, but for the life of me I cannot see the problem.



Many thanks.










share|improve this question
















I have a table mailtable in a backend PostgreSQL database and I'm querying it using SQLAlchemy ORM using a given mailId. For the following code, the amEngine is already set up. When it gets to the mailRow.usercomment = 'Hello World' line, it throws:




AttributeError: can't set attribute




Base = declarative_base()
Base.metadata.reflect(amEngine)
metaAm = MetaData()
metaAm.reflect(bind=amEngine)
mt = metaAm.tables['mailtable']
Session = sessionmaker(bind=amEngine)
amSession = Session()
mailRow = amSession.query(
mt
).filter(
mt.c.id == mailId
).first()
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
amSession.flush()
amSession.commit()


I need to read the address column (successful) and update the usercomment column (throws exception). The PostgreSQL type for both columns is text.
How can I do this? I'm sure this must be a very simple issue, but for the life of me I cannot see the problem.



Many thanks.







python postgresql sqlalchemy






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 27 '18 at 3:09









SuperShoot

1,845720




1,845720










asked Nov 27 '18 at 1:51









Mark WarburtonMark Warburton

8517




8517













  • Related: stackoverflow.com/questions/51391039/…

    – SuperShoot
    Nov 27 '18 at 4:21



















  • Related: stackoverflow.com/questions/51391039/…

    – SuperShoot
    Nov 27 '18 at 4:21

















Related: stackoverflow.com/questions/51391039/…

– SuperShoot
Nov 27 '18 at 4:21





Related: stackoverflow.com/questions/51391039/…

– SuperShoot
Nov 27 '18 at 4:21












2 Answers
2






active

oldest

votes


















3














By calling MetaData.reflect you asked SQLAlchemy to autodetect the Table objects, describing your database. You may use these objects to create language-agnostic SQL queries, such as



engine.execute(update(mt).where(mt.c.id==1).values(usercomment='Hello World'))


You cannot yet use the Table objects to do proper ORM, however. When you query a Table object (via session.query(mt)) you will get the results returned to you as read-only namedtuple-like objects. Setting their attributes makes no sense, hence you observe the exception.



To enjoy actual ORM, you need to create the corresponding ORM classes and map them to the Table objects.



Of course, you can ask SQLAlchemy to auto-reflect the ORM classes for you together with the tables using automap. Here is the code you probably wanted to write:



from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import sessionmaker

# Ask SQLAlchemy to reflect the tables and
# create the corresponding ORM classes:
Base = automap_base()
Base.prepare(amEngine, reflect=True)

# This is the ORM class we are interested in:
MailTable = Base.classes.mailtable

# Create the session, query, update and commit:
Session = sessionmaker(bind=amEngine)
session = Session()
mailRow = session.query(MailTable).get(mailId)
mailAddress = mailRow.address
mailRow.usercomment = 'Hello World'
session.commit()





share|improve this answer


























  • Thanks. That's a very clear and helpful answer.

    – Mark Warburton
    Nov 27 '18 at 5:29



















1














You are querying a Table object directly, not via an instrumented model:



mt = metaAm.tables['mailtable']
print(type(mt))
# <class 'sqlalchemy.sql.schema.Table'>


When you query a table, you are returned an instance of <class 'sqlalchemy.util._collections.result'> which is a type of namedtuple. Tuples are immutable, so you cannot change the value of its attributes.






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%2f53491635%2fsqlalchemy-cant-set-attribute-error-when-updating-value%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    By calling MetaData.reflect you asked SQLAlchemy to autodetect the Table objects, describing your database. You may use these objects to create language-agnostic SQL queries, such as



    engine.execute(update(mt).where(mt.c.id==1).values(usercomment='Hello World'))


    You cannot yet use the Table objects to do proper ORM, however. When you query a Table object (via session.query(mt)) you will get the results returned to you as read-only namedtuple-like objects. Setting their attributes makes no sense, hence you observe the exception.



    To enjoy actual ORM, you need to create the corresponding ORM classes and map them to the Table objects.



    Of course, you can ask SQLAlchemy to auto-reflect the ORM classes for you together with the tables using automap. Here is the code you probably wanted to write:



    from sqlalchemy.ext.automap import automap_base
    from sqlalchemy.orm import sessionmaker

    # Ask SQLAlchemy to reflect the tables and
    # create the corresponding ORM classes:
    Base = automap_base()
    Base.prepare(amEngine, reflect=True)

    # This is the ORM class we are interested in:
    MailTable = Base.classes.mailtable

    # Create the session, query, update and commit:
    Session = sessionmaker(bind=amEngine)
    session = Session()
    mailRow = session.query(MailTable).get(mailId)
    mailAddress = mailRow.address
    mailRow.usercomment = 'Hello World'
    session.commit()





    share|improve this answer


























    • Thanks. That's a very clear and helpful answer.

      – Mark Warburton
      Nov 27 '18 at 5:29
















    3














    By calling MetaData.reflect you asked SQLAlchemy to autodetect the Table objects, describing your database. You may use these objects to create language-agnostic SQL queries, such as



    engine.execute(update(mt).where(mt.c.id==1).values(usercomment='Hello World'))


    You cannot yet use the Table objects to do proper ORM, however. When you query a Table object (via session.query(mt)) you will get the results returned to you as read-only namedtuple-like objects. Setting their attributes makes no sense, hence you observe the exception.



    To enjoy actual ORM, you need to create the corresponding ORM classes and map them to the Table objects.



    Of course, you can ask SQLAlchemy to auto-reflect the ORM classes for you together with the tables using automap. Here is the code you probably wanted to write:



    from sqlalchemy.ext.automap import automap_base
    from sqlalchemy.orm import sessionmaker

    # Ask SQLAlchemy to reflect the tables and
    # create the corresponding ORM classes:
    Base = automap_base()
    Base.prepare(amEngine, reflect=True)

    # This is the ORM class we are interested in:
    MailTable = Base.classes.mailtable

    # Create the session, query, update and commit:
    Session = sessionmaker(bind=amEngine)
    session = Session()
    mailRow = session.query(MailTable).get(mailId)
    mailAddress = mailRow.address
    mailRow.usercomment = 'Hello World'
    session.commit()





    share|improve this answer


























    • Thanks. That's a very clear and helpful answer.

      – Mark Warburton
      Nov 27 '18 at 5:29














    3












    3








    3







    By calling MetaData.reflect you asked SQLAlchemy to autodetect the Table objects, describing your database. You may use these objects to create language-agnostic SQL queries, such as



    engine.execute(update(mt).where(mt.c.id==1).values(usercomment='Hello World'))


    You cannot yet use the Table objects to do proper ORM, however. When you query a Table object (via session.query(mt)) you will get the results returned to you as read-only namedtuple-like objects. Setting their attributes makes no sense, hence you observe the exception.



    To enjoy actual ORM, you need to create the corresponding ORM classes and map them to the Table objects.



    Of course, you can ask SQLAlchemy to auto-reflect the ORM classes for you together with the tables using automap. Here is the code you probably wanted to write:



    from sqlalchemy.ext.automap import automap_base
    from sqlalchemy.orm import sessionmaker

    # Ask SQLAlchemy to reflect the tables and
    # create the corresponding ORM classes:
    Base = automap_base()
    Base.prepare(amEngine, reflect=True)

    # This is the ORM class we are interested in:
    MailTable = Base.classes.mailtable

    # Create the session, query, update and commit:
    Session = sessionmaker(bind=amEngine)
    session = Session()
    mailRow = session.query(MailTable).get(mailId)
    mailAddress = mailRow.address
    mailRow.usercomment = 'Hello World'
    session.commit()





    share|improve this answer















    By calling MetaData.reflect you asked SQLAlchemy to autodetect the Table objects, describing your database. You may use these objects to create language-agnostic SQL queries, such as



    engine.execute(update(mt).where(mt.c.id==1).values(usercomment='Hello World'))


    You cannot yet use the Table objects to do proper ORM, however. When you query a Table object (via session.query(mt)) you will get the results returned to you as read-only namedtuple-like objects. Setting their attributes makes no sense, hence you observe the exception.



    To enjoy actual ORM, you need to create the corresponding ORM classes and map them to the Table objects.



    Of course, you can ask SQLAlchemy to auto-reflect the ORM classes for you together with the tables using automap. Here is the code you probably wanted to write:



    from sqlalchemy.ext.automap import automap_base
    from sqlalchemy.orm import sessionmaker

    # Ask SQLAlchemy to reflect the tables and
    # create the corresponding ORM classes:
    Base = automap_base()
    Base.prepare(amEngine, reflect=True)

    # This is the ORM class we are interested in:
    MailTable = Base.classes.mailtable

    # Create the session, query, update and commit:
    Session = sessionmaker(bind=amEngine)
    session = Session()
    mailRow = session.query(MailTable).get(mailId)
    mailAddress = mailRow.address
    mailRow.usercomment = 'Hello World'
    session.commit()






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 27 '18 at 3:49

























    answered Nov 27 '18 at 3:43









    KT.KT.

    5,40622556




    5,40622556













    • Thanks. That's a very clear and helpful answer.

      – Mark Warburton
      Nov 27 '18 at 5:29



















    • Thanks. That's a very clear and helpful answer.

      – Mark Warburton
      Nov 27 '18 at 5:29

















    Thanks. That's a very clear and helpful answer.

    – Mark Warburton
    Nov 27 '18 at 5:29





    Thanks. That's a very clear and helpful answer.

    – Mark Warburton
    Nov 27 '18 at 5:29













    1














    You are querying a Table object directly, not via an instrumented model:



    mt = metaAm.tables['mailtable']
    print(type(mt))
    # <class 'sqlalchemy.sql.schema.Table'>


    When you query a table, you are returned an instance of <class 'sqlalchemy.util._collections.result'> which is a type of namedtuple. Tuples are immutable, so you cannot change the value of its attributes.






    share|improve this answer






























      1














      You are querying a Table object directly, not via an instrumented model:



      mt = metaAm.tables['mailtable']
      print(type(mt))
      # <class 'sqlalchemy.sql.schema.Table'>


      When you query a table, you are returned an instance of <class 'sqlalchemy.util._collections.result'> which is a type of namedtuple. Tuples are immutable, so you cannot change the value of its attributes.






      share|improve this answer




























        1












        1








        1







        You are querying a Table object directly, not via an instrumented model:



        mt = metaAm.tables['mailtable']
        print(type(mt))
        # <class 'sqlalchemy.sql.schema.Table'>


        When you query a table, you are returned an instance of <class 'sqlalchemy.util._collections.result'> which is a type of namedtuple. Tuples are immutable, so you cannot change the value of its attributes.






        share|improve this answer















        You are querying a Table object directly, not via an instrumented model:



        mt = metaAm.tables['mailtable']
        print(type(mt))
        # <class 'sqlalchemy.sql.schema.Table'>


        When you query a table, you are returned an instance of <class 'sqlalchemy.util._collections.result'> which is a type of namedtuple. Tuples are immutable, so you cannot change the value of its attributes.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 27 '18 at 6:01

























        answered Nov 27 '18 at 3:44









        SuperShootSuperShoot

        1,845720




        1,845720






























            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%2f53491635%2fsqlalchemy-cant-set-attribute-error-when-updating-value%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







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)