Friday, March 28. 2025
Printer Friendly
JSON is one of the most popular ways of disseminating data between systems.
It is probably the most common offered by webservices. PostgreSQL is a database
perfectly suited for grabbing that data and transforming it into a more structured relational format.
All this can be done directly in the database. We'll go over some ways to load and restructure json data.
Continue reading "Converting JSON documents to relational tables"
Wednesday, March 05. 2025
Printer Friendly
Have you ever wanted to get a random integer between 1 and 10 and been a little annoyed the slightly cryptic code you had to write in PostgreSQL?
PostgreSQL 17 random functions make that simpler. Sometimes it's the small changes that bring the most joy.
Continue reading "PG 17 new random functions"
Monday, February 10. 2025
Printer Friendly
After reading Paul's teasing article on
Accessing Large Language Models with AI and testing out his code,
I decided I should probably stop fighting this AI smothering.
I still have a distrust of AI services but downloading an AI model and using on my own local desktop or server is nice and I can break bread with that.
One use I tried is using AI to generate fake data and it did a pretty decent job. I also learned a couple of things.
Continue reading "Learning PostgreSQL from AI and JSON exploration"
Sunday, January 19. 2025
Printer Friendly
One of my favorite uses of JSONB functionality is to unpivot data.
Continue reading "Unpivoting data using JSONB"
Sunday, December 01. 2024
Printer Friendly
I was reviewing some old code when I stumbled across something I must have completely forgotten
or someone else some time ago knew. That is that it is possible to use the function substring for regular expression work.
Continue reading "Substring function Regex style"
Monday, November 25. 2024
Printer Friendly
When I work with other relational databases I am reminded about how I can't use my favorite PostgreSQL hacks in them.
I call these hacks PostgreSQLisms. A PostgreSQLism is a pattern of SQL unique to PostgreSQL or descendants of PostgreSQL.
In this post I'm going to cover some of my favorite ones.
Continue reading "Some of my favorite PostgreSQLisms"
Saturday, June 17. 2017
Printer Friendly
PostgreSQL has a feature
called dollar-quoting,
which allows you to include a body of text without escaping the single quotes. This feature has existed for quite some time.
You've probably seen this in action when defining functions for example:
CREATE OR REPLACE FUNCTION hello_world(param_your_name text)
RETURNS text AS
$$
SELECT 'Hello world. My name is ' || param_your_name || '.';
$$
language sql STRICT;
Which is easier to read, than the equivalent escape quoted function:
CREATE OR REPLACE FUNCTION hello_world(param_your_name text)
RETURNS text AS
'
SELECT ''Hello world. My name is '' || param_your_name || ''.'';
'
language sql STRICT;
Continue reading "Dollar-quoting for escaping single quotes"
Wednesday, October 28. 2015
Printer Friendly
All this time we've been using COPY FROM PROGRAM without any additional adornments. Then we noticed for some things like directory listings in Microsoft windows, it would come across a sequence of inputs it mangled or you may even get an error such as ERROR: end-of-copy marker corrupt.
The trick to get around the issue is to use the FORMAT option. The default FORMAT for COPY FROM PROGRAM is 'text', which tries to escape out some things and in doing so it misinterprets windows slashes so you get weird stuff or no stuff at all.
Continue reading "How to prevent mangling when using COPY FROM PROGRAM"
Tuesday, June 25. 2013
Printer Friendly
We'll be hosting the September 10th, 2013 PostgreSQL User Group meetup
at
Devonshire Sky Club (in the center of Boston Financial district and block away from city hall). This is the same venue we hosted the Boston OSGeo Code Sprint
except this time we'll have some EnterpriseDb folks joining us. Sign-up while supplies last. Leo's got a nice cocktail and food
lineup.
We'll be giving an introductory talk about PostGIS and also give a brief overview of what's packed in the PostGIS 2.1 release that is currently in beta, and that should be out by meetup time. Remember this is the first version of PostGIS to support upcoming PostgreSQL 9.3.
Not only will we have cocktails, but we'll also be giving out PostgreSQL/PostGIS door prizes.
Continue reading "Boston PostgreSQL Meetup September 10, 2013: PostGIS Intro"
Friday, February 08. 2013
Printer Friendly
PostgreSQL allows you to customize statement logging in numerous ways. You can globally set the level of logging you want at both the postgresql.conf (that will affect all databases) or at the database level using the various log_statement* variables. Most of these
are documented in runtime config logging.
For this brief article, we'll talk about the log_line_prefix variable. By default this variable is very minimalistic and just prefixes the log lines with the date time of the statement. If you have just one database (like the way Oracle runs) this is not a big deal,
but if you are like us and run several databases on one PostgreSQL instance, it would be nice to as part of the prefix include the database name.
Continue reading "How to add database name to log output"
Monday, December 31. 2012
Printer Friendly
We recently started upgrading some of our databases on windows 64-bit to 9.2, in doing so we ran into a nasty issue we discovered when some of our backups were failing. The first time it happened, I chucked it up to a dirty PostgreSQL 8.4 database being restored to PostgreSQL 9.2.1. The second time it happened restoring a 9.1 database to 9.2.2, I thought, better look into this to see if there is a known issue. Low and behold I found this:
http://archives.postgresql.org/pgsql-bugs/2012-12/msg00091.php (Bug #7741). Apparently something to do with granting rights on Types.
As a workaround for this problem so our backups would work again was to delete the offending permissions from system tables. It's probably not the best way but only way we could think of, we delete the bad record in pg_default_acl and after that backup works without complaint.
SELECT * into zz_bad_pg_default_acl FROM pg_default_acl WHERE defaclobjtype = 'T';
DELETE from pg_default_acl WHERE defaclobjtype = 'T';
If anyone else has further input on this, I'd be interested.
Wednesday, November 28. 2012
Printer Friendly
This was an article we were meaning to write and got reminded by Szymon Guz latest PostgreSQL search_path behavior.
The PostgreSQL search_path variable allows you to control what order schemas are searched and which schemas do not require schema qualification to use tables/views/functions in the schema. The pg_catalog schema is one that never requires schema qualification even if you don't add it to your schema search_path. Schemas are searched in the order they are listed
and when creating new objects (e.g. tables, views, function, types) that are not schema qualified, they are always created in the first schema of the search path. Any objects not in a schema listed in the search_path must be schema qualified.
Continue reading "Schema and search_path surprises"
Monday, January 16. 2012
Printer Friendly
If I could name a number one feature I love most about PostgreSQL, it's the table inheritance feature which we described in How to Inherit and Uninherit. A lot of people use it for table partitioning using CONSTRAINT EXCLUSION. Aside from that, in combination with PostgreSQL schema search_path (customizable by user and/or database) it makes for a very flexible abstraction tool. For example, for many of our web apps that service many departments where each department/client wants to keep a high level of autonomy, we have a schema set aside for each
that inherits from a master template schema. Each department site uses a different set of accounts with the primary schema being that of the department/client so that they are hitting their own tables.
Inheritance allows us to keep data separate,do roll-up reports if we need to, use the same application front-end, and yet allows us the ability to add new columns in just one place (the master template schema). It is more flexible than other approaches because for example we may have a city organization that need to share tables, like for example a system loaded list of funding source shared across the agency. We can set aside these shared tables in a separate schema visible to all or have some have their own copy they can change if they don't want to use the shared one.
Every once in a while, we find ourselves needing to query the whole hierarchy and needing to know which table the results of the query are coming from. To help
solve that issue, we employ the use of the system column tableoid which all user tables have. The tableoid is the the object id of a table. PostgreSQL has many system columns that you have to explicitly select
and can't be accessed with a SELECT * with the tableoid being one of them. These are: tableoid, cmax,cmin, xmin,xmax,ctid which are all described in System Columns. The PostgreSQL docs on inheritance have examples of using it, but we thought it worthwile to repeat the exercise since it's not that common knowledge and is unique enough feature of PostgreSQL that others coming from other relational databases, may miss the treat. I've often demonstrated
it to non-PostgreSQL users who use for example SQL Server or MySQL, and they literally fall out of their chair when I show the feature to them and its endless possibilities.
Continue reading "Table Inheritance and the tableoid"
Monday, November 21. 2011
Printer Friendly
In this day and age of clouds and what not, it is still important to keep tabs on your database growth to ensure it doesn't
outgrow your disks or so that you can be prepared when it does. A common question that is asked is how big your database is or all your databases combined.
Luckily PostgreSQL has had for a long time functions to help you answer this easily. In this little article,
I'll demonstrate how to answer these questions and more with some PostgreSQL built-in functions
Continue reading "How big is my database and my other stuff"
Tuesday, November 01. 2011
Printer Friendly
Ever have the need to create a holding table say spreadsheet data with say 100 columns. You need to create a table to hold this stuff. Or perhaps you were feeling in a sadist mood and wanted to abuse your PostgreSQL database to see how many columns you can create in a table of a specific data type.
Here is a quick script to do it:
SELECT 'CREATE TABLE data_import('
|| array_to_string(array_agg('field' || i::text || ' varchar(255)'), ',') || ');'
FROM generate_series(1,10) As i;
SELECT 'CREATE TABLE data_import('
|| string_agg('field' || i::text || ' varchar(255)', ',') || ');'
FROM generate_series(1,10) As i;
Both variants will return output that looks like this:
CREATE TABLE data_import(field1 varchar(255),field2 varchar(255),field3 varchar(255),field4 varchar(255)
,field5 varchar(255),field6 varchar(255),field7 varchar(255)
,field8 varchar(255),field9 varchar(255),field10 varchar(255));
Now if you want it to also execute because you are running it as part of an sql script, you could wrap it in an anonymous function.
DO language 'plpgsql'
$$
DECLARE var_sql text := 'CREATE TABLE data_import('
|| string_agg('field' || i::text || ' varchar(255)', ',') || ');'
FROM generate_series(1,10) As i;
BEGIN
EXECUTE var_sql;
END;
$$ ;
|