Skip to content

Commit 7e62368

Browse files
authored
Merge pull request #123 from schireson/dc/idle-in-transaction
fix: Add ability to set session-local idle-in-transaction setting.
2 parents 1541070 + 00c2759 commit 7e62368

5 files changed

Lines changed: 40 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
### v2.9.1
4+
5+
* fix: Add ability to set session-local idle-in-transaction setting
6+
37
### v2.9.0
48

59
* Swap to psycopg from psycopg2

pyproject.toml

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "databudgie"
3-
version = "2.9.0"
3+
version = "2.9.1"
44
description = "Ergonomic and flexible tool for database backup and restore"
55
readme = "README.md"
66
license = { text = "MIT" }
@@ -57,21 +57,7 @@ src = ["src", "tests"]
5757
[tool.ruff.lint]
5858
select = ["C", "D", "E", "F", "I", "N", "Q", "RET", "RUF", "S", "T", "UP", "YTT"]
5959
ignore = ["C901", "E501", "S101", "D1", "D203", "D213", "D406", "D407", "D408", "D409", "D413"]
60-
extend-ignore = [
61-
"D1",
62-
63-
"D203",
64-
"D204",
65-
"D213",
66-
"D215",
67-
"D400",
68-
"D404",
69-
"D406",
70-
"D407",
71-
"D408",
72-
"D409",
73-
"D413",
74-
]
60+
extend-ignore = ["D1", "D203", "D204", "D213", "D215", "D400", "D404", "D406", "D407", "D408", "D409", "D413"]
7561

7662
[tool.ruff.lint.isort]
7763
order-by-type = false

src/databudgie/cli/base.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,14 @@ def _create_postgres_session(config: BackupConfig | RestoreConfig):
4343
url_obj = sqlalchemy.engine.url.make_url(url)
4444

4545
engine = sqlalchemy.create_engine(url_obj)
46-
return sqlalchemy.orm.scoping.scoped_session(sqlalchemy.orm.session.sessionmaker(bind=engine))()
46+
session = sqlalchemy.orm.scoping.scoped_session(sqlalchemy.orm.session.sessionmaker(bind=engine))()
47+
48+
if config.idle_in_transaction_timeout is not None:
49+
session.execute(
50+
sqlalchemy.text(f"SET idle_in_transaction_session_timeout = '{config.idle_in_transaction_timeout}s'")
51+
)
52+
53+
return session
4754

4855

4956
def backup_config(root_config: RootConfig):

src/databudgie/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class TableParentConfig(typing.Generic[T], Config):
141141
s3: S3Config | None = None
142142
root_location: str | None = None
143143
adapter: str | None = None
144+
idle_in_transaction_timeout: int | None = None
144145

145146
@classmethod
146147
@abc.abstractmethod
@@ -168,6 +169,8 @@ def from_stack(cls, stack: ConfigStack):
168169

169170
connections = Connection.from_collection(stack.get("connections"))
170171

172+
idle_in_transaction_timeout = stack.get("idle_in_transaction_timeout")
173+
171174
return cls(
172175
connection=connection,
173176
tables=tables,
@@ -177,6 +180,7 @@ def from_stack(cls, stack: ConfigStack):
177180
root_location=root_location,
178181
adapter=adapter,
179182
connections=connections,
183+
idle_in_transaction_timeout=idle_in_transaction_timeout,
180184
)
181185

182186

tests/test_backup.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,28 @@ def test_backup_unnamed_table(pg, mf, s3_resource):
195195
)
196196

197197

198+
def test_backup_with_idle_in_transaction_timeout(pg, s3_resource):
199+
"""Validate backup works with idle_in_transaction_timeout config option."""
200+
config = RootConfig.from_dict(
201+
{
202+
"location": "s3://sample-bucket/databudgie/test/{table}",
203+
"tables": ["public.customer", "public.store"],
204+
"sequences": False,
205+
"strict": True,
206+
"idle_in_transaction_timeout": 5000,
207+
**s3_config,
208+
}
209+
)
210+
211+
backup_all(pg, config.backup)
212+
213+
all_object_keys = [obj.key for obj in s3_resource.Bucket("sample-bucket").objects.all()]
214+
assert all_object_keys == [
215+
"databudgie/test/public.customer/2021-04-26T09:00:00.csv",
216+
"databudgie/test/public.store/2021-04-26T09:00:00.csv",
217+
]
218+
219+
198220
def _validate_backup_contents(buffer, expected_contents: List[Customer]):
199221
"""Validate the contents of a backup file. Columns from the file will be raw."""
200222
wrapper = io.TextIOWrapper(buffer, encoding="utf-8")

0 commit comments

Comments
 (0)