Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9f37267
feat(types): implement PostgreSQL DataType subclasses and type suppor…
vistart Jun 19, 2026
493b3b1
refactor(types): add __eq__/__hash__, remove synonyms, add CharacterV…
vistart Jun 20, 2026
69752c1
feat(schema): add parsed_data_type to PostgreSQL _parse_columns
vistart Jun 20, 2026
eb74b59
feat(types): add synonyms to PostgreSQL types
vistart Jun 20, 2026
0709ab7
feat(types): add synonyms to PostgresByteaType
vistart Jun 20, 2026
a018e70
refactor(types): inherit DDLTypeMixin in Postgres type formatting
vistart Jun 20, 2026
58528ca
refactor(types): update to DDLTypeSupport protocol
vistart Jun 20, 2026
6657f4a
refactor(types): use @DDLTypeMixin.handles, remove format_data_type o…
vistart Jun 20, 2026
906ca0c
fix(types): rewrite Postgres core type formatters, fix missing Postgr…
vistart Jun 20, 2026
982eedc
feat(postgres): implement array type support
vistart Jun 20, 2026
9140634
refactor(postgres): use core ArrayType, keep PostgresArrayType as alias
vistart Jun 20, 2026
7868029
feat(postgres): add element type validation and PostgresArrayType sub…
vistart Jun 20, 2026
580e2f8
feat(schema): add PostgresSchemaDiffer
vistart Jun 20, 2026
2638e00
feat(schema): add schema-diff examples and refactor for PostgreSQL ba…
vistart Jun 21, 2026
dc9100d
refactor(types): remove _default_sql(), make format_data_type return …
vistart Jun 21, 2026
8109ce4
style(types): add complete type annotations to all format_data_type_*…
vistart Jun 21, 2026
65de5c6
feat(examples): strengthen serialization roundtrip with table data as…
vistart Jun 21, 2026
7c56a73
fix(tests): replace string data_type with DataType instances across 2…
vistart Jun 24, 2026
3ee0c28
docs: add changelog fragment for PR #46
vistart Jun 24, 2026
18b65ef
fix(tests): replace positional string data_type with DataType instanc…
vistart Jun 24, 2026
bafef40
fix(types): register PostgresCitextType, PostgresCubeType, PostgresLt…
vistart Jun 24, 2026
bfa91de
fix: restore PostgresCidrType import accidentally removed in type for…
vistart Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/46.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added PostgreSQL-specific DataType subclasses and schema-diff support with `PostgresSchemaDiffer` for accurate schema introspection and column comparison.
97 changes: 97 additions & 0 deletions src/rhosocial/activerecord/backend/impl/postgres/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,55 @@
from .dialect import PostgresDialect
from .transaction import PostgresTransactionManager, AsyncPostgresTransactionManager
from .types import PostgresEnumType
from .expression.types import (
PostgresBigSerialType,
PostgresBitType,
PostgresBoxType,
PostgresByteaType,
PostgresCIDType,
PostgresCircleType,
PostgresDateMultirangeType,
PostgresDateRangeType,
PostgresGeographyType,
PostgresGeometryType,
PostgresHstoreType,
PostgresInetType,
PostgresInt4MultirangeType,
PostgresInt4RangeType,
PostgresInt8MultirangeType,
PostgresInt8RangeType,
PostgresJsonPathType,
PostgresLineSegmentType,
PostgresLineType,
PostgresMacAddr8Type,
PostgresMacAddrType,
PostgresMoneyType,
PostgresNumMultirangeType,
PostgresNumRangeType,
PostgresOIDType,
PostgresPathType,
PostgresPgLSNType,
PostgresPointType,
PostgresPolygonType,
PostgresRegClassType,
PostgresRegTypeType,
PostgresSerialType,
PostgresSmallSerialType,
PostgresTIDType,
PostgresTSQueryType,
PostgresTSVectorType,
PostgresTsMultirangeType,
PostgresTsRangeType,
PostgresTsTzMultirangeType,
PostgresTsTzRangeType,
PostgresUUIDType,
PostgresVarBitType,
PostgresVectorType,
PostgresXID8Type,
PostgresXIDType,
PostgresXMLType,
PostgresCidrType,
)
from .explain import PostgresExplainResult, PostgresExplainPlanLine
from .expression.ddl import (
PostgresCreateEnumTypeExpression,
Expand Down Expand Up @@ -505,4 +554,52 @@
# hstore functions - Subscript
"hstore_subscript_get",
"hstore_subscript_set",
# PostgreSQL DataType subclasses for DDL
"PostgresBigSerialType",
"PostgresBitType",
"PostgresBoxType",
"PostgresByteaType",
"PostgresCIDType",
"PostgresCircleType",
"PostgresDateMultirangeType",
"PostgresDateRangeType",
"PostgresGeographyType",
"PostgresGeometryType",
"PostgresHstoreType",
"PostgresInetType",
"PostgresInt4MultirangeType",
"PostgresInt4RangeType",
"PostgresInt8MultirangeType",
"PostgresInt8RangeType",
"PostgresJsonPathType",
"PostgresLineSegmentType",
"PostgresLineType",
"PostgresMacAddr8Type",
"PostgresMacAddrType",
"PostgresMoneyType",
"PostgresNumMultirangeType",
"PostgresNumRangeType",
"PostgresOIDType",
"PostgresPathType",
"PostgresPgLSNType",
"PostgresPointType",
"PostgresPolygonType",
"PostgresRegClassType",
"PostgresRegTypeType",
"PostgresSerialType",
"PostgresSmallSerialType",
"PostgresTIDType",
"PostgresTSQueryType",
"PostgresTSVectorType",
"PostgresTsMultirangeType",
"PostgresTsRangeType",
"PostgresTsTzMultirangeType",
"PostgresTsTzRangeType",
"PostgresUUIDType",
"PostgresVarBitType",
"PostgresVectorType",
"PostgresXID8Type",
"PostgresXIDType",
"PostgresXMLType",
"PostgresCidrType",
]
5 changes: 5 additions & 0 deletions src/rhosocial/activerecord/backend/impl/postgres/dialect.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
IntrospectionSupport,
TransactionControlSupport,
SQLFunctionSupport,
DDLTypeSupport,
)
from .mixins import (
PostgresExtensionMixin,
Expand Down Expand Up @@ -169,6 +170,7 @@
PostgresRangeTypeMixin,
PostgresJSONBEnhancedMixin,
PostgresArrayEnhancedMixin,
PostgresTypeFormatSupportMixin,
# DDL/DML operation mixins (new)
PostgresExtendedStatisticsMixin,
PostgresStoredProcedureMixin,
Expand Down Expand Up @@ -400,6 +402,7 @@ class PostgresDialect(
PostgresFullTextSearchMixin,
PostgresRangeTypeMixin,
PostgresArrayEnhancedMixin,
PostgresTypeFormatSupportMixin,
# DDL/DML operation mixins (new)
PostgresExtendedStatisticsMixin,
PostgresStoredProcedureMixin,
Expand Down Expand Up @@ -524,6 +527,8 @@ class PostgresDialect(
PostgresRangeTypeSupport,
PostgresJSONBEnhancedSupport,
PostgresArrayEnhancedSupport,
# DataType Support Protocol
DDLTypeSupport,
# New feature protocols
PostgresParallelQuerySupport,
PostgresStoredProcedureSupport,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,4 +416,46 @@
'max_version': '18',
'note': 'Requires superuser or pg_read_server_files role; only available in PG15+ docker images',
},
'schema_diff/table_changes.py': {
'title': 'Schema Diff — Table Add/Remove',
'dialect_protocols': [],
'priority': 10,
'min_version': '9',
'max_version': '18',
},
'schema_diff/column_order_irrelevant.py': {
'title': 'Schema Diff — Column Order Is Ignored',
'dialect_protocols': [],
'priority': 10,
'min_version': '9',
'max_version': '18',
},
'schema_diff/postgres10_identity.py': {
'title': 'Schema Diff — PG9 SERIAL vs PG10+ IDENTITY',
'dialect_protocols': [],
'priority': 10,
'min_version': '9',
'max_version': '18',
},
'schema_diff/array_type_diff.py': {
'title': 'Schema Diff — Array Type Dimension Changes',
'dialect_protocols': [],
'priority': 10,
'min_version': '9',
'max_version': '18',
},
'schema_diff/index_type_diff.py': {
'title': 'Schema Diff — PostgreSQL Index Type Switches',
'dialect_protocols': [],
'priority': 10,
'min_version': '9',
'max_version': '18',
},
'schema_diff/serialization_roundtrip.py': {
'title': 'Schema Diff — Snapshot Serialization Roundtrip',
'dialect_protocols': [],
'priority': 10,
'min_version': '9',
'max_version': '18',
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

drop_table = DropTableExpression(
dialect=dialect,
table_name='users',
table='users',
if_exists=True,
cascade=True,
)
Expand All @@ -47,7 +47,7 @@

create_table = CreateTableExpression(
dialect=dialect,
table_name='users',
table='users',
columns=[
ColumnDefinition(
'id',
Expand Down Expand Up @@ -148,13 +148,23 @@
print("Column renamed successfully")

# Verify table structure
options = ExecutionOptions(stmt_type=StatementType.DQL)
result = backend.execute(
"SELECT column_name, data_type, is_nullable "
"FROM information_schema.columns "
"WHERE table_name = 'users' ORDER BY ordinal_position",
options=options
from rhosocial.activerecord.backend.expression import QueryExpression, TableExpression
from rhosocial.activerecord.backend.expression.core import WildcardExpression, Column
from rhosocial.activerecord.backend.expression.query_parts import OrderByClause

verify_expr = QueryExpression(
dialect=dialect,
select=[
Column(dialect, 'column_name'),
Column(dialect, 'data_type'),
Column(dialect, 'is_nullable'),
],
from_=TableExpression(dialect, 'columns', schema_name='information_schema'),
where=Column(dialect, 'table_name') == Literal(dialect, 'users'),
order_by=OrderByClause(dialect, [Column(dialect, 'ordinal_position')]),
)
options = ExecutionOptions(stmt_type=StatementType.DQL)
result = backend.execute(*verify_expr.to_sql(), options=options)
print("Table structure after alterations:")
for row in result.data or []:
print(f" {row}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

drop_table = DropTableExpression(
dialect=dialect,
table_name='products',
table='products',
if_exists=True,
cascade=True,
)
Expand All @@ -42,7 +42,7 @@

create_table = CreateTableExpression(
dialect=dialect,
table_name='products',
table='products',
columns=[
ColumnDefinition(
'id',
Expand Down Expand Up @@ -83,11 +83,17 @@
print("Index created: idx_category_price")

# Verify index creation
options = ExecutionOptions(stmt_type=StatementType.DQL)
verify_result = backend.execute(
"SELECT indexname FROM pg_indexes WHERE indexname = 'idx_category_price'",
options=options
from rhosocial.activerecord.backend.expression import QueryExpression, TableExpression
from rhosocial.activerecord.backend.expression.core import Column, Literal

verify_expr = QueryExpression(
dialect=dialect,
select=[Column(dialect, 'indexname')],
from_=TableExpression(dialect, 'pg_indexes'),
where=Column(dialect, 'indexname') == Literal(dialect, 'idx_category_price'),
)
options = ExecutionOptions(stmt_type=StatementType.DQL)
verify_result = backend.execute(*verify_expr.to_sql(), options=options)
print(f"Index info: {verify_result.data}")

# ============================================================
Expand Down
Loading
Loading