sqlalchemy-events-lib 0.3.2__tar.gz → 0.3.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/PKG-INFO +1 -1
  2. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/pyproject.toml +1 -1
  3. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/__init__.py +1 -1
  4. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/init_triggers_strategies/postgres_init_triggers.py +12 -15
  5. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events_lib.egg-info/PKG-INFO +1 -1
  6. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/test_is_created_triggers.py +13 -6
  7. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/LICENSE +0 -0
  8. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/README.md +0 -0
  9. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/setup.cfg +0 -0
  10. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/callbacks_strategies/__init__.py +0 -0
  11. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/callbacks_strategies/base.py +0 -0
  12. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/callbacks_strategies/postgres_callback.py +0 -0
  13. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/core.py +0 -0
  14. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/decorators.py +0 -0
  15. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/default_logger.py +0 -0
  16. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/discovery.py +0 -0
  17. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/events.py +0 -0
  18. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/exceptions.py +0 -0
  19. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/handlers.py +0 -0
  20. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/init_triggers_strategies/__init__.py +0 -0
  21. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/init_triggers_strategies/base.py +0 -0
  22. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/registry.py +0 -0
  23. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/types.py +0 -0
  24. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events/utils.py +0 -0
  25. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events_lib.egg-info/SOURCES.txt +0 -0
  26. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events_lib.egg-info/dependency_links.txt +0 -0
  27. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events_lib.egg-info/requires.txt +0 -0
  28. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/sqlalchemy_events_lib.egg-info/top_level.txt +0 -0
  29. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/conftest.py +0 -0
  30. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/test_autodiscover.py +0 -0
  31. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/test_handlers.py +0 -0
  32. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/test_models.py +0 -0
  33. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/test_sa_events.py +0 -0
  34. {sqlalchemy_events_lib-0.3.2 → sqlalchemy_events_lib-0.3.3}/src/tests/test_with_events_deco.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlalchemy-events-lib
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Event-driven extension for SQLAlchemy that enables listening to database CUD events. This library allows you to react to database changes in real time using a clean, declarative API.
5
5
  Author-email: Alexey Kostarev <normjkeeewm@gmail.com>
6
6
  License: MIT
@@ -10,7 +10,7 @@ where = ["src"]
10
10
 
11
11
  [project]
12
12
  name = "sqlalchemy-events-lib"
13
- version = "0.3.2"
13
+ version = "0.3.3"
14
14
  description = "Event-driven extension for SQLAlchemy that enables listening to database CUD events. This library allows you to react to database changes in real time using a clean, declarative API."
15
15
  requires-python = ">=3.12"
16
16
  authors = [
@@ -11,4 +11,4 @@ __all__ = [
11
11
  'with_events',
12
12
  'SaEvent'
13
13
  ]
14
- __version__ = '0.3.2'
14
+ __version__ = '0.3.3'
@@ -10,6 +10,8 @@ from .base import InitTriggersStrategy
10
10
  class PostgresInitTriggers(InitTriggersStrategy):
11
11
 
12
12
  async def __call__(self, model_list: list[Type[DeclarativeBase]], conn, logger):
13
+ result = await conn.execute(text("SELECT current_schema()"))
14
+ schema = result.scalar()
13
15
  for sa_event in SaEvent:
14
16
  sa_event = sa_event.lower()
15
17
  await conn.execute(
@@ -21,7 +23,7 @@ class PostgresInitTriggers(InitTriggersStrategy):
21
23
  BEGIN
22
24
  payload := json_build_object(
23
25
  'op', '{sa_event}',
24
- 'table', TG_TABLE_NAME,
26
+ 'table', TG_full_name,
25
27
  'rows', array_agg(n.id)
26
28
  )
27
29
  FROM {'old_rows' if sa_event.upper() == SaEvent.DELETE else 'new_rows'} n;
@@ -40,23 +42,18 @@ class PostgresInitTriggers(InitTriggersStrategy):
40
42
  continue
41
43
 
42
44
  table_name = cls.__tablename__
43
-
45
+ full_name = f'{schema}.{table_name}'
44
46
  existing_triggers = set()
45
47
 
46
48
  table_exists = await conn.scalar(
47
- text("""
48
- SELECT EXISTS (SELECT 1
49
- FROM pg_class
50
- WHERE relname = :tbl
51
- AND relkind = 'r')
52
- """),
53
- {'tbl': table_name},
49
+ text('SELECT to_regclass(:tbl) IS NOT NULL'),
50
+ {'tbl': full_name},
54
51
  )
55
52
  if not table_exists:
56
53
  if logger:
57
54
  logger.warning(f"[SQLAlchemyEvents] {cls.__name__} has "
58
55
  f"{'event' if len(events) == 1 else 'events'} {', '.join(events)}, "
59
- f"but relation '{table_name}' does not exist")
56
+ f"but relation '{full_name}' does not exist")
60
57
  continue
61
58
 
62
59
  if table_exists:
@@ -67,26 +64,26 @@ class PostgresInitTriggers(InitTriggersStrategy):
67
64
  AND NOT tgisinternal
68
65
  """)
69
66
 
70
- for row in await conn.execute(tg_sql, {'tbl': table_name}):
67
+ for row in await conn.execute(tg_sql, {'tbl': full_name}):
71
68
  existing_triggers.add(row[0])
72
69
 
73
70
  added_events = []
74
71
  for event in sorted(events):
75
72
  l_event = event.lower()
76
- trig_name = f'sa_{table_name}_{l_event}_notify'
73
+ trig_name = f'sa_{schema}_{table_name}_{l_event}_notify'
77
74
 
78
75
  if trig_name in existing_triggers:
79
76
  continue
80
77
 
81
78
  added_events.append(event)
82
79
  await conn.execute(
83
- text(f'DROP TRIGGER IF EXISTS {trig_name} ON {table_name};')
80
+ text(f'DROP TRIGGER IF EXISTS {trig_name} ON {full_name};')
84
81
  )
85
82
 
86
83
  await conn.execute(
87
84
  text(f"""
88
85
  CREATE TRIGGER {trig_name}
89
- AFTER {event} ON {table_name}
86
+ AFTER {event} ON {full_name}
90
87
  REFERENCING {'OLD' if event == SaEvent.DELETE else 'NEW'}
91
88
  TABLE AS {'old_rows' if event == SaEvent.DELETE else 'new_rows'}
92
89
  FOR EACH STATEMENT
@@ -97,7 +94,7 @@ class PostgresInitTriggers(InitTriggersStrategy):
97
94
  if added_events and logger:
98
95
  logger.info(
99
96
  f"Detected added {'event' if len(added_events) == 1 else 'events'} "
100
- f"{', '.join(added_events)} for table '{table_name}'"
97
+ f"{', '.join(added_events)} for table '{full_name}'"
101
98
  )
102
99
 
103
100
  await conn.commit()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlalchemy-events-lib
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Event-driven extension for SQLAlchemy that enables listening to database CUD events. This library allows you to react to database changes in real time using a clean, declarative API.
5
5
  Author-email: Alexey Kostarev <normjkeeewm@gmail.com>
6
6
  License: MIT
@@ -3,21 +3,28 @@ from sqlalchemy import text
3
3
 
4
4
  async def test_is_created_triggers(session):
5
5
  trigger_names = [
6
- 'sa_users_delete_notify',
7
- 'sa_users_insert_notify',
8
- 'sa_users_update_notify',
6
+ 'sa_public_users_delete_notify',
7
+ 'sa_public_users_insert_notify',
8
+ 'sa_public_users_update_notify',
9
9
  ]
10
-
10
+ result = await session.execute(text('SELECT current_schema()'))
11
+ schema = result.scalar()
11
12
  result = await session.execute(
12
13
  text("""
13
14
  SELECT COUNT(*)
14
15
  FROM pg_trigger t
15
16
  JOIN pg_class c ON t.tgrelid = c.oid
16
- WHERE c.relname = 'users'
17
+ JOIN pg_namespace n ON c.relnamespace = n.oid
18
+ WHERE c.relname = :table
19
+ AND n.nspname = :schema
17
20
  AND t.tgname = ANY (:trigger_names)
18
21
  AND NOT t.tgisinternal
19
22
  """),
20
- {'trigger_names': trigger_names}
23
+ {
24
+ 'table': 'users',
25
+ 'schema': schema,
26
+ 'trigger_names': trigger_names,
27
+ }
21
28
  )
22
29
 
23
30
  count = result.scalar()