Materialized view not updating











up vote
0
down vote

favorite












I have a materialised view that basically keeps track of all vouchers used at checkout so I can keep track of how many have been used, how many are left etc. I have only just noticed that the materialized view wont update, It currently shows the following:



enter image description here



Where left obviously decreases as vouchers are used (voucher type and vouchers used along with the user id of who used it are in different tables). It has however detected that one voucher has been used but as for the other 2 I used on testing it won't pick them up from the table where used vouchers are stored and update the MV.



Here is part of the migration I currently have for making the MV:



exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`);
};


I have the feeling that I have used the materialized view incorrectly and that it only ran the query in the migration once (when I initially implemented the mv).



EDIT



For extra information here are the other 2 tables I have:



vouchers:



enter image description here



order_vouchers:



enter image description here










share|improve this question
























  • Which dbms is it?
    – GolezTrol
    Nov 8 at 11:51










  • Currently using Postgres
    – JvB
    Nov 8 at 11:52










  • @GolezTrol Also added the tables I use to create the MV for extra context
    – JvB
    Nov 8 at 11:57










  • The reason I asked, is I don't think it's related to knex. I think maybe you need to specify somewhere that the MV should update automatically. Depending on the database, you can configure them to update real time, periodically or on demand. I don't know Postgress that well, but I'd check the docs for MV's in Postgress to see whether something like that is the matter.
    – GolezTrol
    Nov 8 at 12:02










  • Thank you for the response, I shall have a look!
    – JvB
    Nov 8 at 12:03















up vote
0
down vote

favorite












I have a materialised view that basically keeps track of all vouchers used at checkout so I can keep track of how many have been used, how many are left etc. I have only just noticed that the materialized view wont update, It currently shows the following:



enter image description here



Where left obviously decreases as vouchers are used (voucher type and vouchers used along with the user id of who used it are in different tables). It has however detected that one voucher has been used but as for the other 2 I used on testing it won't pick them up from the table where used vouchers are stored and update the MV.



Here is part of the migration I currently have for making the MV:



exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`);
};


I have the feeling that I have used the materialized view incorrectly and that it only ran the query in the migration once (when I initially implemented the mv).



EDIT



For extra information here are the other 2 tables I have:



vouchers:



enter image description here



order_vouchers:



enter image description here










share|improve this question
























  • Which dbms is it?
    – GolezTrol
    Nov 8 at 11:51










  • Currently using Postgres
    – JvB
    Nov 8 at 11:52










  • @GolezTrol Also added the tables I use to create the MV for extra context
    – JvB
    Nov 8 at 11:57










  • The reason I asked, is I don't think it's related to knex. I think maybe you need to specify somewhere that the MV should update automatically. Depending on the database, you can configure them to update real time, periodically or on demand. I don't know Postgress that well, but I'd check the docs for MV's in Postgress to see whether something like that is the matter.
    – GolezTrol
    Nov 8 at 12:02










  • Thank you for the response, I shall have a look!
    – JvB
    Nov 8 at 12:03













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a materialised view that basically keeps track of all vouchers used at checkout so I can keep track of how many have been used, how many are left etc. I have only just noticed that the materialized view wont update, It currently shows the following:



enter image description here



Where left obviously decreases as vouchers are used (voucher type and vouchers used along with the user id of who used it are in different tables). It has however detected that one voucher has been used but as for the other 2 I used on testing it won't pick them up from the table where used vouchers are stored and update the MV.



Here is part of the migration I currently have for making the MV:



exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`);
};


I have the feeling that I have used the materialized view incorrectly and that it only ran the query in the migration once (when I initially implemented the mv).



EDIT



For extra information here are the other 2 tables I have:



vouchers:



enter image description here



order_vouchers:



enter image description here










share|improve this question















I have a materialised view that basically keeps track of all vouchers used at checkout so I can keep track of how many have been used, how many are left etc. I have only just noticed that the materialized view wont update, It currently shows the following:



enter image description here



Where left obviously decreases as vouchers are used (voucher type and vouchers used along with the user id of who used it are in different tables). It has however detected that one voucher has been used but as for the other 2 I used on testing it won't pick them up from the table where used vouchers are stored and update the MV.



Here is part of the migration I currently have for making the MV:



exports.up = function(knex, Promise) {
return knex.schema
.raw(`
CREATE MATERIALIZED VIEW mv_vouchers as
SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
FROM public.vouchers v LEFT OUTER JOIN
public.order_vouchers ov
ON v.voucher_id = ov.voucher_id
GROUP BY v.voucher_id, v.quantity;
`);
};


I have the feeling that I have used the materialized view incorrectly and that it only ran the query in the migration once (when I initially implemented the mv).



EDIT



For extra information here are the other 2 tables I have:



vouchers:



enter image description here



order_vouchers:



enter image description here







sql postgresql migration knex.js materialized-views






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 11:53

























asked Nov 8 at 11:49









JvB

7910




7910












  • Which dbms is it?
    – GolezTrol
    Nov 8 at 11:51










  • Currently using Postgres
    – JvB
    Nov 8 at 11:52










  • @GolezTrol Also added the tables I use to create the MV for extra context
    – JvB
    Nov 8 at 11:57










  • The reason I asked, is I don't think it's related to knex. I think maybe you need to specify somewhere that the MV should update automatically. Depending on the database, you can configure them to update real time, periodically or on demand. I don't know Postgress that well, but I'd check the docs for MV's in Postgress to see whether something like that is the matter.
    – GolezTrol
    Nov 8 at 12:02










  • Thank you for the response, I shall have a look!
    – JvB
    Nov 8 at 12:03


















  • Which dbms is it?
    – GolezTrol
    Nov 8 at 11:51










  • Currently using Postgres
    – JvB
    Nov 8 at 11:52










  • @GolezTrol Also added the tables I use to create the MV for extra context
    – JvB
    Nov 8 at 11:57










  • The reason I asked, is I don't think it's related to knex. I think maybe you need to specify somewhere that the MV should update automatically. Depending on the database, you can configure them to update real time, periodically or on demand. I don't know Postgress that well, but I'd check the docs for MV's in Postgress to see whether something like that is the matter.
    – GolezTrol
    Nov 8 at 12:02










  • Thank you for the response, I shall have a look!
    – JvB
    Nov 8 at 12:03
















Which dbms is it?
– GolezTrol
Nov 8 at 11:51




Which dbms is it?
– GolezTrol
Nov 8 at 11:51












Currently using Postgres
– JvB
Nov 8 at 11:52




Currently using Postgres
– JvB
Nov 8 at 11:52












@GolezTrol Also added the tables I use to create the MV for extra context
– JvB
Nov 8 at 11:57




@GolezTrol Also added the tables I use to create the MV for extra context
– JvB
Nov 8 at 11:57












The reason I asked, is I don't think it's related to knex. I think maybe you need to specify somewhere that the MV should update automatically. Depending on the database, you can configure them to update real time, periodically or on demand. I don't know Postgress that well, but I'd check the docs for MV's in Postgress to see whether something like that is the matter.
– GolezTrol
Nov 8 at 12:02




The reason I asked, is I don't think it's related to knex. I think maybe you need to specify somewhere that the MV should update automatically. Depending on the database, you can configure them to update real time, periodically or on demand. I don't know Postgress that well, but I'd check the docs for MV's in Postgress to see whether something like that is the matter.
– GolezTrol
Nov 8 at 12:02












Thank you for the response, I shall have a look!
– JvB
Nov 8 at 12:03




Thank you for the response, I shall have a look!
– JvB
Nov 8 at 12:03












2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










The MV is basically just a table, except it also remembers which query it should execute to update (actually replace) its contents.



I think Postgres doesn't have any parameter for automatically refreshing the MV, either live or periodically.



The data is queried and stored when you create the view, except when you specify WITH NO DATA, in which case it's create empty.



You can then (re)populate the view on demand by calling REFRESH MATERIALIZED VIEW.






share|improve this answer




























    up vote
    0
    down vote













    Just thought I would add a quick solution to this:



    exports.up = function(knex, Promise) {
    return knex.schema
    .raw(`
    CREATE MATERIALIZED VIEW mv_vouchers as
    SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
    FROM public.vouchers v LEFT OUTER JOIN
    public.order_vouchers ov
    ON v.voucher_id = ov.voucher_id
    GROUP BY v.voucher_id, v.quantity;
    `)
    .raw(`
    CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
    BEGIN
    REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
    RETURN null;
    END $$;
    `)
    .raw(`
    CREATE TRIGGER refresh_mv_vouchers
    AFTER insert OR update OR delete OR truncate
    ON order_vouchers
    EXECUTE PROCEDURE refresh_mv_vouchers();
    `);
    };

    exports.down = function(knex, Promise) {
    return knex.schema
    .raw('DROP MATERIALIZED VIEW mv_vouchers')
    .raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
    .raw('DROP FUNCTION refresh_mv_vouchers()');
    };


    Was a lot more straight forward than I initially thought.






    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',
      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%2f53207150%2fmaterialized-view-not-updating%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








      up vote
      1
      down vote



      accepted










      The MV is basically just a table, except it also remembers which query it should execute to update (actually replace) its contents.



      I think Postgres doesn't have any parameter for automatically refreshing the MV, either live or periodically.



      The data is queried and stored when you create the view, except when you specify WITH NO DATA, in which case it's create empty.



      You can then (re)populate the view on demand by calling REFRESH MATERIALIZED VIEW.






      share|improve this answer

























        up vote
        1
        down vote



        accepted










        The MV is basically just a table, except it also remembers which query it should execute to update (actually replace) its contents.



        I think Postgres doesn't have any parameter for automatically refreshing the MV, either live or periodically.



        The data is queried and stored when you create the view, except when you specify WITH NO DATA, in which case it's create empty.



        You can then (re)populate the view on demand by calling REFRESH MATERIALIZED VIEW.






        share|improve this answer























          up vote
          1
          down vote



          accepted







          up vote
          1
          down vote



          accepted






          The MV is basically just a table, except it also remembers which query it should execute to update (actually replace) its contents.



          I think Postgres doesn't have any parameter for automatically refreshing the MV, either live or periodically.



          The data is queried and stored when you create the view, except when you specify WITH NO DATA, in which case it's create empty.



          You can then (re)populate the view on demand by calling REFRESH MATERIALIZED VIEW.






          share|improve this answer












          The MV is basically just a table, except it also remembers which query it should execute to update (actually replace) its contents.



          I think Postgres doesn't have any parameter for automatically refreshing the MV, either live or periodically.



          The data is queried and stored when you create the view, except when you specify WITH NO DATA, in which case it's create empty.



          You can then (re)populate the view on demand by calling REFRESH MATERIALIZED VIEW.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 8 at 12:08









          GolezTrol

          96.8k9128171




          96.8k9128171
























              up vote
              0
              down vote













              Just thought I would add a quick solution to this:



              exports.up = function(knex, Promise) {
              return knex.schema
              .raw(`
              CREATE MATERIALIZED VIEW mv_vouchers as
              SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
              FROM public.vouchers v LEFT OUTER JOIN
              public.order_vouchers ov
              ON v.voucher_id = ov.voucher_id
              GROUP BY v.voucher_id, v.quantity;
              `)
              .raw(`
              CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
              BEGIN
              REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
              RETURN null;
              END $$;
              `)
              .raw(`
              CREATE TRIGGER refresh_mv_vouchers
              AFTER insert OR update OR delete OR truncate
              ON order_vouchers
              EXECUTE PROCEDURE refresh_mv_vouchers();
              `);
              };

              exports.down = function(knex, Promise) {
              return knex.schema
              .raw('DROP MATERIALIZED VIEW mv_vouchers')
              .raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
              .raw('DROP FUNCTION refresh_mv_vouchers()');
              };


              Was a lot more straight forward than I initially thought.






              share|improve this answer

























                up vote
                0
                down vote













                Just thought I would add a quick solution to this:



                exports.up = function(knex, Promise) {
                return knex.schema
                .raw(`
                CREATE MATERIALIZED VIEW mv_vouchers as
                SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
                FROM public.vouchers v LEFT OUTER JOIN
                public.order_vouchers ov
                ON v.voucher_id = ov.voucher_id
                GROUP BY v.voucher_id, v.quantity;
                `)
                .raw(`
                CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
                BEGIN
                REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
                RETURN null;
                END $$;
                `)
                .raw(`
                CREATE TRIGGER refresh_mv_vouchers
                AFTER insert OR update OR delete OR truncate
                ON order_vouchers
                EXECUTE PROCEDURE refresh_mv_vouchers();
                `);
                };

                exports.down = function(knex, Promise) {
                return knex.schema
                .raw('DROP MATERIALIZED VIEW mv_vouchers')
                .raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
                .raw('DROP FUNCTION refresh_mv_vouchers()');
                };


                Was a lot more straight forward than I initially thought.






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Just thought I would add a quick solution to this:



                  exports.up = function(knex, Promise) {
                  return knex.schema
                  .raw(`
                  CREATE MATERIALIZED VIEW mv_vouchers as
                  SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
                  FROM public.vouchers v LEFT OUTER JOIN
                  public.order_vouchers ov
                  ON v.voucher_id = ov.voucher_id
                  GROUP BY v.voucher_id, v.quantity;
                  `)
                  .raw(`
                  CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
                  BEGIN
                  REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
                  RETURN null;
                  END $$;
                  `)
                  .raw(`
                  CREATE TRIGGER refresh_mv_vouchers
                  AFTER insert OR update OR delete OR truncate
                  ON order_vouchers
                  EXECUTE PROCEDURE refresh_mv_vouchers();
                  `);
                  };

                  exports.down = function(knex, Promise) {
                  return knex.schema
                  .raw('DROP MATERIALIZED VIEW mv_vouchers')
                  .raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
                  .raw('DROP FUNCTION refresh_mv_vouchers()');
                  };


                  Was a lot more straight forward than I initially thought.






                  share|improve this answer












                  Just thought I would add a quick solution to this:



                  exports.up = function(knex, Promise) {
                  return knex.schema
                  .raw(`
                  CREATE MATERIALIZED VIEW mv_vouchers as
                  SELECT v.voucher_id, v.quantity, COUNT(ov.voucher_id) AS "used", v.quantity - COUNT(ov.voucher_id) AS "left"
                  FROM public.vouchers v LEFT OUTER JOIN
                  public.order_vouchers ov
                  ON v.voucher_id = ov.voucher_id
                  GROUP BY v.voucher_id, v.quantity;
                  `)
                  .raw(`
                  CREATE FUNCTION refresh_mv_vouchers() RETURNS trigger LANGUAGE plpgsql AS $$
                  BEGIN
                  REFRESH MATERIALIZED VIEW CONCURRENTLY mv_vouchers;
                  RETURN null;
                  END $$;
                  `)
                  .raw(`
                  CREATE TRIGGER refresh_mv_vouchers
                  AFTER insert OR update OR delete OR truncate
                  ON order_vouchers
                  EXECUTE PROCEDURE refresh_mv_vouchers();
                  `);
                  };

                  exports.down = function(knex, Promise) {
                  return knex.schema
                  .raw('DROP MATERIALIZED VIEW mv_vouchers')
                  .raw('DROP TRIGGER refresh_mv_vouchers ON order_vouchers')
                  .raw('DROP FUNCTION refresh_mv_vouchers()');
                  };


                  Was a lot more straight forward than I initially thought.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 8 at 12:32









                  JvB

                  7910




                  7910






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53207150%2fmaterialized-view-not-updating%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

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)