pgAdmin 7.0 exposes PostgreSQL null-aware uniqueness
pgAdmin adds a control for NULLS NOT DISTINCT while updating its own runtime and server-mode behavior.
A unique constraint does not necessarily prevent repeated missing values. PostgreSQL normally treats nulls as distinct for uniqueness, so a nullable business identifier can appear in several otherwise conflicting rows. pgAdmin 4 v7.0 adds a control for choosing the alternative behavior already available in PostgreSQL 15. That small interface change exposes an important schema decision to people using the graphical editor.
The release notes for version 7.0 date the release April 13. They identify issue 5855 as the option to create unique constraints with nulls not distinct. The PostgreSQL-site announcement provides a separate overview and packaging guidance. The database implements the constraint, while pgAdmin supplies another way to express it.
I prefer PostgreSQL schemas that state their rules explicitly. A graphical tool helps when it makes an existing rule visible without changing its meaning. Null treatment is particularly suitable for an explicit control because a familiar word such as unique can conceal different expectations.
Null treatment changes which rows conflict
The PostgreSQL 15 constraint documentation specifies the default. Two null values do not count as equal when PostgreSQL checks a unique constraint. For a multicolumn constraint, a null in at least one constrained column can therefore allow rows whose remaining constrained values match.
Adding NULLS NOT DISTINCT changes that comparison. Missing values then participate in uniqueness as equivalent nulls. This does not require the column to contain a value, which remains the purpose of NOT NULL. It controls whether repeated missing values conflict with one another.
A schema can use that distinction for an optional external identifier. Ordinary uniqueness allows multiple rows with no assigned identifier. Nulls-not-distinct uniqueness allows only one such row for a single constrained column. Neither interpretation is universally correct. The choice depends on what a missing identifier means in the data model.
For composite keys the question becomes more specific. If a constraint covers a tenant identifier and an optional name, the chosen null behavior determines whether one tenant can have several unnamed entries. The rule applies to the constrained combination, not to an independent global count of nulls. The PostgreSQL documentation defines composite uniqueness in terms of all constrained columns.
Version 7.0 does not introduce this behavior to older PostgreSQL servers. Its supported-server list includes PostgreSQL 11 through 15, but a client's support range does not imply that every server implements every DDL option. The capability belongs to the server version, and the editor exposes the option for expressing the applicable schema rule.
Editing constraints and identifying objects
The same release expands the row-edit form automatically when adding a primary key, foreign key, unique constraint or exclusion constraint. That change belongs to the interaction around defining a constraint. It does not alter how PostgreSQL validates data, and the distinction matters when interpreting a management-tool release as a database feature announcement.
Another change copies an object's fully qualified name when the user presses Ctrl+C on a tree object. A qualified name carries schema context that a bare object name omits. That helps transfer the identity of the selected object into another task without requiring a reader to infer its schema from the surrounding tree.
The release also renames the Browser tree to Object Explorer and changes the Properties context-menu label to Edit Object. Those are direct interface changes documented in the release notes. Together with the constraint editor work, they concern the tool's representation of database objects rather than a change to PostgreSQL's object model.
My interest in these controls is practical. Database tooling should preserve the distinction between selecting an object and modifying its definition, because the schema remains the durable contract after the editing session ends.
Server mode has its own dependencies
Version 7.0 adds support for mounted shared storage in server mode. It also ensures that user storage directories exist both for newly created users and for users whose directories have not yet been created. These changes concern the hosted management application, which has state and filesystem behavior separate from the databases it manages.
The runtime dependencies change as well. The release upgrades from psycopg2 to psycopg3 and updates SQLAlchemy, Flask and Flask-SQLAlchemy. It removes Bootstrap and jQuery usage. These changes explain why a management-tool upgrade includes application deployment considerations even when a PostgreSQL server requires no corresponding major-version migration.
There is also a security correction for simultaneous LDAP login attempts, identified as CVE-2023-1907. The release notes name the issue without supplying a full exploitation mechanism. Its presence is enough to identify authentication as part of the update, but not enough to invent details about which identities an attacker could obtain.
The PostgreSQL-site announcement gives specific upgrade guidance for RHEL 8, Rocky Linux 8, Fedora 36 and Fedora 37. It requires manually removing python3-mod_wsgi and notes the dependency removal affecting pgAdmin. That instruction belongs to those package upgrades. The release's graphical schema improvements and its Python dependency transition therefore have different deployment consequences, even though they arrive in the same version.