{"id":30443,"date":"2024-01-25T13:15:17","date_gmt":"2024-01-25T12:15:17","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=30443"},"modified":"2024-02-13T09:42:42","modified_gmt":"2024-02-13T08:42:42","slug":"postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/","title":{"rendered":"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy"},"content":{"rendered":"\n<p>In one of the <a href=\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-copy-and-save_error_to\/\" target=\"_blank\" rel=\"noreferrer noopener\">last posts <\/a>we&#8217;ve looked at how you tell copy to ignore any rows which do not fit into the target table starting with PostgreSQL 17. While this is great, this also hides information you maybe would like to know: How many rows have been discarded during the load? This <a href=\"https:\/\/git.postgresql.org\/gitweb\/?p=postgresql.git;a=commitdiff;h=729439607ad210dbb446e31754e8627d7e3f7dda\" target=\"_blank\" rel=\"noreferrer noopener\">commit<\/a> goes into that direction and extends <a href=\"https:\/\/www.postgresql.org\/docs\/devel\/progress-reporting.html#COPY-PROGRESS-REPORTING\" target=\"_blank\" rel=\"noreferrer noopener\">pg_stat_progress_copy<\/a> with an additional column: tuples_skipped. This does not record how many rows have been skipped after the load, but at least you now can monitor how many rows have been skipped while the data load is running.<\/p>\n\n\n\n<p>For having a look at this, we cannot use a very small text file as in the last post, this will load too fast:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3,6]; title: ; notranslate\" title=\"\">\npostgres=# create table import ( a int, b varchar(4), c int, d varchar(4));\nCREATE TABLE\npostgres=# copy import from &#039;\/home\/postgres\/data.txt&#039; with (delimiter &#039; &#039;);\nCOPY 8\n-- second\/another session\npostgres=# select * from pg_stat_progress_copy ;\n pid | datid | datname | relid | command | type | bytes_processed | bytes_total | tuples_processed | tuples_excluded | tuples_skipped \n-----+-------+---------+-------+---------+------+-----------------+-------------+------------------+-----------------+----------------\n(0 rows)\n<\/pre><\/div>\n\n\n<p>To really see something in <a href=\"https:\/\/www.postgresql.org\/docs\/devel\/progress-reporting.html#COPY-PROGRESS-REPORTING\" target=\"_blank\" rel=\"noreferrer noopener\">pg_stat_progress_copy<\/a> lets generate a simple, but larger, data set:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,3,5]; title: ; notranslate\" title=\"\">\npostgres=# create table t ( a varchar(50), b varchar(50) );\nCREATE TABLE\npostgres=# insert into t select md5(i::text), md5(i::text) from generate_series(1,3000000) i;\nINSERT 0 3000000\npostgres=# copy t to &#039;\/var\/tmp\/a&#039;;\nCOPY 3000000\npostgres=# \\! head \/var\/tmp\/a\nc4ca4238a0b923820dcc509a6f75849b        c4ca4238a0b923820dcc509a6f75849b\nc81e728d9d4c2f636f067f89cc14862c        c81e728d9d4c2f636f067f89cc14862c\neccbc87e4b5ce2fe28308fd9f2a7baf3        eccbc87e4b5ce2fe28308fd9f2a7baf3\na87ff679a2f3e71d9181a67b7542122c        a87ff679a2f3e71d9181a67b7542122c\ne4da3b7fbbce2345d7772b0674a318d5        e4da3b7fbbce2345d7772b0674a318d5\n1679091c5a880faf6fb5e6087eb1b2dc        1679091c5a880faf6fb5e6087eb1b2dc\n8f14e45fceea167a5a36dedd4bea2543        8f14e45fceea167a5a36dedd4bea2543\nc9f0f895fb98ab9159f51fd0297e236d        c9f0f895fb98ab9159f51fd0297e236d\n45c48cce2e2d7fbdea1afc51c7c6ad26        45c48cce2e2d7fbdea1afc51c7c6ad26\nd3d9446802a44259755d38e6d163e820        d3d9446802a44259755d38e6d163e820\n<\/pre><\/div>\n\n\n<p>This gives us a simple text file with two hashed columns. Before loading this, we&#8217;ll introduce some rows which will not fit into the table:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,2,3,4,5,6]; title: ; notranslate\" title=\"\">\npostgres=# \\! sed -i &#039;1500000 i 123456789012345678901234567890123456789012345678901234567890&#039; \/var\/tmp\/a\npostgres=# \\! sed -i &#039;1500000 i 123456789012345678901234567890123456789012345678901234567890&#039; \/var\/tmp\/a\npostgres=# \\! sed -i &#039;1500000 i 123456789012345678901234567890123456789012345678901234567890&#039; \/var\/tmp\/a\npostgres=# \\! sed -i &#039;1500000 i 123456789012345678901234567890123456789012345678901234567890&#039; \/var\/tmp\/a\npostgres=# \\! sed -i &#039;1500000 i 123456789012345678901234567890123456789012345678901234567890&#039; \/var\/tmp\/a\npostgres=# \\! grep 123456789012345678901234567890123456789012345678901234567890 \/var\/tmp\/a\n123456789012345678901234567890123456789012345678901234567890\n123456789012345678901234567890123456789012345678901234567890\n123456789012345678901234567890123456789012345678901234567890\n123456789012345678901234567890123456789012345678901234567890\n123456789012345678901234567890123456789012345678901234567890\n<\/pre><\/div>\n\n\n<p>Those 60 characters will not fit into the first columns and will fail to load. Before loading this, we start a second session and monitor <a href=\"https:\/\/www.postgresql.org\/docs\/devel\/progress-reporting.html#COPY-PROGRESS-REPORTING\" target=\"_blank\" rel=\"noreferrer noopener\">pg_stat_progress_copy<\/a>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [1,5]; title: ; notranslate\" title=\"\">\npostgres=# select datname, tuples_processed, tuples_skipped from pg_stat_progress_copy ;\n datname | tuples_processed | tuples_skipped \n---------+------------------+----------------\n(0 rows)\npostgres=# \\watch 1 \n Thu 25 Jan 2024 01:08:31 PM CET (every 1s)\n\n datname | tuples_processed | tuples_skipped \n---------+------------------+----------------\n(0 rows)\n...\n<\/pre><\/div>\n\n\n<p>In the first session we&#8217;ll create a new table with the same structure as the previous one and start to load the data:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; highlight: [1,3]; title: ; notranslate\" title=\"\">\npostgres=# create table z ( like t );\nCREATE TABLE\npostgres=# copy z from &#039;\/var\/tmp\/a&#039; with ( ON_ERROR &#039;ignore&#039; );\nCOPY 3000000\n<\/pre><\/div>\n\n\n<p>In the second session we&#8217;ll see that exactly the five row have been skipped we&#8217;ve added above:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; highlight: [16]; title: ; notranslate\" title=\"\">\n datname | tuples_processed | tuples_skipped \n---------+------------------+----------------\n(0 rows)\n\n  Thu 25 Jan 2024 01:11:18 PM CET (every 1s)\n\n datname  | tuples_processed | tuples_skipped \n----------+------------------+----------------\n postgres |           163000 |              0\n(1 row)\n\n  Thu 25 Jan 2024 01:11:19 PM CET (every 1s)\n\n datname  | tuples_processed | tuples_skipped \n----------+------------------+----------------\n postgres |          2346000 |              5\n(1 row)\n\n Thu 25 Jan 2024 01:11:20 PM CET (every 1s)\n\n datname | tuples_processed | tuples_skipped \n---------+------------------+----------------\n(0 rows)\n<\/pre><\/div>\n\n\n<p>Nice, thanks to all involved.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In one of the last posts we&#8217;ve looked at how you tell copy to ignore any rows which do not fit into the target table starting with PostgreSQL 17. While this is great, this also hides information you maybe would like to know: How many rows have been discarded during the load? This commit goes [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[229,198],"tags":[2602],"type_dbi":[],"class_list":["post-30443","post","type-post","status-publish","format-standard","hentry","category-database-administration-monitoring","category-database-management","tag-postgresql-2"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy\" \/>\n<meta property=\"og:description\" content=\"In one of the last posts we&#8217;ve looked at how you tell copy to ignore any rows which do not fit into the target table starting with PostgreSQL 17. While this is great, this also hides information you maybe would like to know: How many rows have been discarded during the load? This commit goes [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-01-25T12:15:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-13T08:42:42+00:00\" \/>\n<meta name=\"author\" content=\"Daniel Westermann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@westermanndanie\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Daniel Westermann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\"},\"author\":{\"name\":\"Daniel Westermann\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"headline\":\"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy\",\"datePublished\":\"2024-01-25T12:15:17+00:00\",\"dateModified\":\"2024-02-13T08:42:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\"},\"wordCount\":256,\"commentCount\":0,\"keywords\":[\"postgresql\"],\"articleSection\":[\"Database Administration &amp; Monitoring\",\"Database management\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\",\"name\":\"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"datePublished\":\"2024-01-25T12:15:17+00:00\",\"dateModified\":\"2024-02-13T08:42:42+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66\",\"name\":\"Daniel Westermann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g\",\"caption\":\"Daniel Westermann\"},\"description\":\"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.\",\"sameAs\":[\"https:\/\/x.com\/westermanndanie\"],\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/","og_locale":"en_US","og_type":"article","og_title":"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy","og_description":"In one of the last posts we&#8217;ve looked at how you tell copy to ignore any rows which do not fit into the target table starting with PostgreSQL 17. While this is great, this also hides information you maybe would like to know: How many rows have been discarded during the load? This commit goes [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/","og_site_name":"dbi Blog","article_published_time":"2024-01-25T12:15:17+00:00","article_modified_time":"2024-02-13T08:42:42+00:00","author":"Daniel Westermann","twitter_card":"summary_large_image","twitter_creator":"@westermanndanie","twitter_misc":{"Written by":"Daniel Westermann","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/"},"author":{"name":"Daniel Westermann","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"headline":"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy","datePublished":"2024-01-25T12:15:17+00:00","dateModified":"2024-02-13T08:42:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/"},"wordCount":256,"commentCount":0,"keywords":["postgresql"],"articleSection":["Database Administration &amp; Monitoring","Database management"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/","url":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/","name":"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"datePublished":"2024-01-25T12:15:17+00:00","dateModified":"2024-02-13T08:42:42+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/postgresql-17-track-skipped-rows-from-copy-in-pg_stat_progress_copy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"PostgreSQL 17: Track skipped rows from COPY in pg_stat_progress_copy"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/8d08e9bd996a89bd75c0286cbabf3c66","name":"Daniel Westermann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/31350ceeecb1dd8986339a29bf040d4cd3cd087d410deccd8f55234466d6c317?s=96&d=mm&r=g","caption":"Daniel Westermann"},"description":"Daniel Westermann is Principal Consultant and Technology Leader Open Infrastructure at dbi services. He has more than 15 years of experience in management, engineering and optimization of databases and infrastructures, especially on Oracle and PostgreSQL. Since the beginning of his career, he has specialized in Oracle Technologies and is Oracle Certified Professional 12c and Oracle Certified Expert RAC\/GridInfra. Over time, Daniel has become increasingly interested in open source technologies, becoming \u201cTechnology Leader Open Infrastructure\u201d and PostgreSQL expert. \u00a0Based on community or EnterpriseDB tools, he develops and installs complex high available solutions with PostgreSQL. He is also a certified PostgreSQL Plus 9.0 Professional and a Postgres Advanced Server 9.4 Professional. He is a regular speaker at PostgreSQL conferences in Switzerland and Europe. Today Daniel is also supporting our customers on AWS services such as AWS RDS, database migrations into the cloud, EC2 and automated infrastructure management with AWS SSM (System Manager). He is a certified AWS Solutions Architect Professional. Prior to dbi services, Daniel was Management System Engineer at LC SYSTEMS-Engineering AG in Basel. Before that, he worked as Oracle Developper &amp;\u00a0Project Manager at Delta Energy Solutions AG in Basel (today Powel AG). Daniel holds a diploma in Business Informatics (DHBW, Germany). His branch-related experience mainly covers the pharma industry, the financial sector, energy, lottery and telecommunications.","sameAs":["https:\/\/x.com\/westermanndanie"],"url":"https:\/\/www.dbi-services.com\/blog\/author\/daniel-westermann\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/30443","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=30443"}],"version-history":[{"count":4,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/30443\/revisions"}],"predecessor-version":[{"id":30447,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/30443\/revisions\/30447"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=30443"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=30443"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=30443"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=30443"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}