sqlalchemy-risingwave 1.4.1__tar.gz → 2.0.0__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 (25) hide show
  1. sqlalchemy_risingwave-2.0.0/PKG-INFO +179 -0
  2. sqlalchemy_risingwave-2.0.0/README.md +143 -0
  3. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/setup.cfg +1 -0
  4. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/setup.py +3 -3
  5. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave/__init__.py +1 -1
  6. sqlalchemy_risingwave-2.0.0/sqlalchemy_risingwave/base.py +642 -0
  7. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave/requirements.py +17 -1
  8. sqlalchemy_risingwave-2.0.0/sqlalchemy_risingwave.egg-info/PKG-INFO +179 -0
  9. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave.egg-info/SOURCES.txt +3 -1
  10. sqlalchemy_risingwave-2.0.0/sqlalchemy_risingwave.egg-info/requires.txt +1 -0
  11. sqlalchemy_risingwave-2.0.0/test/test_schema.py +146 -0
  12. sqlalchemy_risingwave-2.0.0/test/test_tenant.py +61 -0
  13. sqlalchemy_risingwave-2.0.0/test/test_usage.py +224 -0
  14. sqlalchemy_risingwave-1.4.1/PKG-INFO +0 -91
  15. sqlalchemy_risingwave-1.4.1/README.md +0 -56
  16. sqlalchemy_risingwave-1.4.1/sqlalchemy_risingwave/base.py +0 -278
  17. sqlalchemy_risingwave-1.4.1/sqlalchemy_risingwave.egg-info/PKG-INFO +0 -91
  18. sqlalchemy_risingwave-1.4.1/sqlalchemy_risingwave.egg-info/requires.txt +0 -1
  19. sqlalchemy_risingwave-1.4.1/test/test_schema.py +0 -68
  20. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/LICENSE +0 -0
  21. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave/psycopg2.py +0 -0
  22. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave.egg-info/dependency_links.txt +0 -0
  23. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave.egg-info/entry_points.txt +0 -0
  24. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave.egg-info/not-zip-safe +0 -0
  25. {sqlalchemy_risingwave-1.4.1 → sqlalchemy_risingwave-2.0.0}/sqlalchemy_risingwave.egg-info/top_level.txt +0 -0
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: sqlalchemy-risingwave
3
+ Version: 2.0.0
4
+ Summary: RisingWave dialect for SQLAlchemy
5
+ Home-page: https://github.com/risingwavelabs/risingwave
6
+ Author: RisingWave Labs
7
+ Author-email: risingwave@dev.com
8
+ License: http://www.apache.org/licenses/LICENSE-2.0
9
+ Project-URL: Source, https://github.com/risingwavelabs/sqlalchemy-risingwave
10
+ Project-URL: Tracker, https://github.com/risingwavelabs/sqlalchemy-risingwave/issues
11
+ Keywords: SQLAlchemy RisingWave
12
+ Classifier: License :: OSI Approved :: Apache Software License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: SQLAlchemy<2.1,>=2.0
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: description-content-type
28
+ Dynamic: home-page
29
+ Dynamic: keywords
30
+ Dynamic: license
31
+ Dynamic: license-file
32
+ Dynamic: project-url
33
+ Dynamic: requires-dist
34
+ Dynamic: requires-python
35
+ Dynamic: summary
36
+
37
+ # RisingWave dialect for SQLAlchemy
38
+
39
+ SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL. https://www.sqlalchemy.org/
40
+
41
+ RisingWave is a cloud-native streaming database that uses SQL as the interface language. It is designed to reduce the complexity and cost of building real-time applications. https://www.risingwave.com
42
+
43
+ ## Prerequisites
44
+
45
+ For psycopg2 support you must install either:
46
+
47
+ * [psycopg2](https://pypi.org/project/psycopg2/), which has some
48
+ [prerequisites](https://www.psycopg.org/docs/install.html#prerequisites) of
49
+ its own.
50
+
51
+ * [psycopg2-binary](https://pypi.org/project/psycopg2-binary/)
52
+
53
+ (The binary package is a practical choice for development and testing but in
54
+ production it is advised to use the package built from sources.)
55
+
56
+ ## Install
57
+ Install via [PyPI](https://pypi.org/project/sqlalchemy-risingwave/)
58
+ ```
59
+ pip install sqlalchemy-risingwave
60
+ ```
61
+
62
+ Recommend install packages locally like below. If directly from PyPI, the version may not be the most updated.
63
+
64
+ ```
65
+ python setup.py sdist bdist_wheel # generate dist
66
+ pip install -e . # install this package
67
+ ```
68
+
69
+ ## Usage
70
+ `sqlalchemy-risingwave` will work like a plugin to be placed into runtime sqlalchemy lib, so that we can overrides some code path to change the behaviour to better fits these python clients with RisingWave.
71
+
72
+ See how to use with Superset: [doc](./doc/integrate_with_superset.md)
73
+
74
+ ## SQLAlchemy compatibility
75
+
76
+ This dialect targets SQLAlchemy 2.0+. RisingWave's SQL surface is
77
+ PostgreSQL-compatible for *querying*, but diverges from PostgreSQL OLTP
78
+ semantics for several features the SQLAlchemy ORM and most non-streaming
79
+ tooling assume. This section documents that gap honestly rather than papering
80
+ over it.
81
+
82
+ The upstream `sqlalchemy.testing.suite` dialect compliance suite runs against
83
+ a real RisingWave instance via
84
+ [`.github/workflows/compliance.yml`](.github/workflows/compliance.yml). It is
85
+ **advisory** (`continue-on-error: true`) — its job is to quantify the gap, not
86
+ to gate merges. The current baseline on `main` is:
87
+
88
+ | Result | Count | Meaning |
89
+ |---|---|---|
90
+ | Pass | 90 | Behaviour the dialect implements as PG-compatible |
91
+ | Fail | 281 | RisingWave streaming semantics diverge from the assertion (see below) |
92
+ | Skip | 946 | Features RisingWave does not implement; declared unsupported via `Requirements` and the advisory harness |
93
+ | Error | 0 | Fixture or collection errors (none expected on `main`) |
94
+
95
+ That is `90 / (90 + 281) ≈ 24%` of tests whose assertion RisingWave can
96
+ express, and `90 / 1317 ≈ 6.8%` of the suite overall. The 946 skips are
97
+ honest "the database does not support this" signals, not silent passes.
98
+
99
+ ### Safe fallbacks the dialect applies
100
+
101
+ These rewrites change how SQLAlchemy renders DDL so the RisingWave parser
102
+ accepts it. Importantly they only re-shape syntax that RisingWave **already
103
+ does not enforce in PostgreSQL semantics either**, so the rewrite is a no-op
104
+ at the data layer — not a silent change to a user-declared invariant:
105
+
106
+ * `SERIAL` / `BIGSERIAL` / `SMALLSERIAL` → `INTEGER` / `BIGINT` / `SMALLINT`
107
+ ([PR #49](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/49)).
108
+ RisingWave does not implement PostgreSQL per-row autoincrement, so inserts
109
+ must supply explicit ids.
110
+ * `CHAR(n)` / `VARCHAR(n)` / `NUMERIC(p, s)` / `DECIMAL(p, s)` →
111
+ unparameterised forms
112
+ ([PR #50](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/50)).
113
+ RisingWave does not enforce length / precision caps.
114
+ * `Uuid()` / `UUID` → `VARCHAR` with SQLAlchemy non-native UUID round-trip
115
+ ([PR #51](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/51)).
116
+ Format validation moves to the application layer.
117
+ * `Enum(...)` → `VARCHAR` (`supports_native_enum = False`)
118
+ ([PR #51](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/51)).
119
+ Note that the optional `CHECK` constraint SQLAlchemy generates for
120
+ non-native enums is also not enforced by RisingWave (see below).
121
+
122
+ ### User-declared invariants the dialect does NOT silently drop
123
+
124
+ Silently rewriting these would let an application's data model assumptions
125
+ break without anyone noticing, so the dialect does not strip, emulate, or
126
+ pretend to enforce them. Depending on the RisingWave version and construct,
127
+ RisingWave may reject the DDL or accept metadata that is not enforced at
128
+ runtime; in either case, the application must not rely on the dialect to
129
+ provide the invariant:
130
+
131
+ * `CHECK` constraints — not enforced by RisingWave.
132
+ * `UNIQUE` constraints — not enforced.
133
+ * `FOREIGN KEY` constraints — declared but not enforced at runtime.
134
+
135
+ If your application depends on any of these invariants today, enforce them at
136
+ the application layer or in the ingest pipeline before data lands in
137
+ RisingWave.
138
+
139
+ ### Read-after-write
140
+
141
+ An `INSERT` enters the streaming pipeline and is not necessarily visible to a
142
+ subsequent `SELECT` in the same connection until the change crosses a
143
+ checkpoint barrier. This is a property of RisingWave's streaming model, not a
144
+ bug in the dialect. SQLAlchemy's ORM and the upstream compliance suite assume
145
+ PostgreSQL OLTP semantics (`INSERT` then `SELECT` returns the row), and that
146
+ assumption is the root cause of nearly all of the 281 advisory failures.
147
+
148
+ See [`docs/streaming.md`](docs/streaming.md) for the trade-offs and how to
149
+ think about this in application code.
150
+
151
+ ### Where this fits in CI
152
+
153
+ * Every pull request runs the dialect's own `test/` suite against a real
154
+ RisingWave instance across Python 3.10 / 3.11 / 3.12 / 3.13. This suite is
155
+ merge-gating: a green build means the documented dialect behaviour above
156
+ still holds.
157
+ * Pull requests that touch the dialect or the compliance harness also run the
158
+ upstream SQLAlchemy compliance suite via `compliance.yml`. That run is
159
+ advisory and produces a `compliance-log` artifact for triage.
160
+
161
+ ## Develop
162
+ Install pre-req.
163
+ ```
164
+ pip install sqlalchemy alembic pytest psycopg2-binary
165
+ ```
166
+
167
+ ### Test
168
+ We use pytest for unittest.
169
+ ```
170
+ pytest # to run the test
171
+ ```
172
+
173
+ ## Ref
174
+
175
+ - [Sqlalchemy dialects doc](https://github.com/sqlalchemy/sqlalchemy/blob/main/README.dialects.rst)
176
+ - [CocoroachDB sqlalchemy](https://github.com/cockroachdb/sqlalchemy-cockroachdb)
177
+ - [RisingWave: Open-Source Streaming Database](https://www.risingwave.com/database/)
178
+ - [RisingWave Cloud](https://www.risingwave.com/cloud/)
179
+ - [What is RisingWave?](https://docs.risingwave.com/docs/current/intro/)
@@ -0,0 +1,143 @@
1
+ # RisingWave dialect for SQLAlchemy
2
+
3
+ SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that gives application developers the full power and flexibility of SQL. https://www.sqlalchemy.org/
4
+
5
+ RisingWave is a cloud-native streaming database that uses SQL as the interface language. It is designed to reduce the complexity and cost of building real-time applications. https://www.risingwave.com
6
+
7
+ ## Prerequisites
8
+
9
+ For psycopg2 support you must install either:
10
+
11
+ * [psycopg2](https://pypi.org/project/psycopg2/), which has some
12
+ [prerequisites](https://www.psycopg.org/docs/install.html#prerequisites) of
13
+ its own.
14
+
15
+ * [psycopg2-binary](https://pypi.org/project/psycopg2-binary/)
16
+
17
+ (The binary package is a practical choice for development and testing but in
18
+ production it is advised to use the package built from sources.)
19
+
20
+ ## Install
21
+ Install via [PyPI](https://pypi.org/project/sqlalchemy-risingwave/)
22
+ ```
23
+ pip install sqlalchemy-risingwave
24
+ ```
25
+
26
+ Recommend install packages locally like below. If directly from PyPI, the version may not be the most updated.
27
+
28
+ ```
29
+ python setup.py sdist bdist_wheel # generate dist
30
+ pip install -e . # install this package
31
+ ```
32
+
33
+ ## Usage
34
+ `sqlalchemy-risingwave` will work like a plugin to be placed into runtime sqlalchemy lib, so that we can overrides some code path to change the behaviour to better fits these python clients with RisingWave.
35
+
36
+ See how to use with Superset: [doc](./doc/integrate_with_superset.md)
37
+
38
+ ## SQLAlchemy compatibility
39
+
40
+ This dialect targets SQLAlchemy 2.0+. RisingWave's SQL surface is
41
+ PostgreSQL-compatible for *querying*, but diverges from PostgreSQL OLTP
42
+ semantics for several features the SQLAlchemy ORM and most non-streaming
43
+ tooling assume. This section documents that gap honestly rather than papering
44
+ over it.
45
+
46
+ The upstream `sqlalchemy.testing.suite` dialect compliance suite runs against
47
+ a real RisingWave instance via
48
+ [`.github/workflows/compliance.yml`](.github/workflows/compliance.yml). It is
49
+ **advisory** (`continue-on-error: true`) — its job is to quantify the gap, not
50
+ to gate merges. The current baseline on `main` is:
51
+
52
+ | Result | Count | Meaning |
53
+ |---|---|---|
54
+ | Pass | 90 | Behaviour the dialect implements as PG-compatible |
55
+ | Fail | 281 | RisingWave streaming semantics diverge from the assertion (see below) |
56
+ | Skip | 946 | Features RisingWave does not implement; declared unsupported via `Requirements` and the advisory harness |
57
+ | Error | 0 | Fixture or collection errors (none expected on `main`) |
58
+
59
+ That is `90 / (90 + 281) ≈ 24%` of tests whose assertion RisingWave can
60
+ express, and `90 / 1317 ≈ 6.8%` of the suite overall. The 946 skips are
61
+ honest "the database does not support this" signals, not silent passes.
62
+
63
+ ### Safe fallbacks the dialect applies
64
+
65
+ These rewrites change how SQLAlchemy renders DDL so the RisingWave parser
66
+ accepts it. Importantly they only re-shape syntax that RisingWave **already
67
+ does not enforce in PostgreSQL semantics either**, so the rewrite is a no-op
68
+ at the data layer — not a silent change to a user-declared invariant:
69
+
70
+ * `SERIAL` / `BIGSERIAL` / `SMALLSERIAL` → `INTEGER` / `BIGINT` / `SMALLINT`
71
+ ([PR #49](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/49)).
72
+ RisingWave does not implement PostgreSQL per-row autoincrement, so inserts
73
+ must supply explicit ids.
74
+ * `CHAR(n)` / `VARCHAR(n)` / `NUMERIC(p, s)` / `DECIMAL(p, s)` →
75
+ unparameterised forms
76
+ ([PR #50](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/50)).
77
+ RisingWave does not enforce length / precision caps.
78
+ * `Uuid()` / `UUID` → `VARCHAR` with SQLAlchemy non-native UUID round-trip
79
+ ([PR #51](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/51)).
80
+ Format validation moves to the application layer.
81
+ * `Enum(...)` → `VARCHAR` (`supports_native_enum = False`)
82
+ ([PR #51](https://github.com/risingwavelabs/sqlalchemy-risingwave/pull/51)).
83
+ Note that the optional `CHECK` constraint SQLAlchemy generates for
84
+ non-native enums is also not enforced by RisingWave (see below).
85
+
86
+ ### User-declared invariants the dialect does NOT silently drop
87
+
88
+ Silently rewriting these would let an application's data model assumptions
89
+ break without anyone noticing, so the dialect does not strip, emulate, or
90
+ pretend to enforce them. Depending on the RisingWave version and construct,
91
+ RisingWave may reject the DDL or accept metadata that is not enforced at
92
+ runtime; in either case, the application must not rely on the dialect to
93
+ provide the invariant:
94
+
95
+ * `CHECK` constraints — not enforced by RisingWave.
96
+ * `UNIQUE` constraints — not enforced.
97
+ * `FOREIGN KEY` constraints — declared but not enforced at runtime.
98
+
99
+ If your application depends on any of these invariants today, enforce them at
100
+ the application layer or in the ingest pipeline before data lands in
101
+ RisingWave.
102
+
103
+ ### Read-after-write
104
+
105
+ An `INSERT` enters the streaming pipeline and is not necessarily visible to a
106
+ subsequent `SELECT` in the same connection until the change crosses a
107
+ checkpoint barrier. This is a property of RisingWave's streaming model, not a
108
+ bug in the dialect. SQLAlchemy's ORM and the upstream compliance suite assume
109
+ PostgreSQL OLTP semantics (`INSERT` then `SELECT` returns the row), and that
110
+ assumption is the root cause of nearly all of the 281 advisory failures.
111
+
112
+ See [`docs/streaming.md`](docs/streaming.md) for the trade-offs and how to
113
+ think about this in application code.
114
+
115
+ ### Where this fits in CI
116
+
117
+ * Every pull request runs the dialect's own `test/` suite against a real
118
+ RisingWave instance across Python 3.10 / 3.11 / 3.12 / 3.13. This suite is
119
+ merge-gating: a green build means the documented dialect behaviour above
120
+ still holds.
121
+ * Pull requests that touch the dialect or the compliance harness also run the
122
+ upstream SQLAlchemy compliance suite via `compliance.yml`. That run is
123
+ advisory and produces a `compliance-log` artifact for triage.
124
+
125
+ ## Develop
126
+ Install pre-req.
127
+ ```
128
+ pip install sqlalchemy alembic pytest psycopg2-binary
129
+ ```
130
+
131
+ ### Test
132
+ We use pytest for unittest.
133
+ ```
134
+ pytest # to run the test
135
+ ```
136
+
137
+ ## Ref
138
+
139
+ - [Sqlalchemy dialects doc](https://github.com/sqlalchemy/sqlalchemy/blob/main/README.dialects.rst)
140
+ - [CocoroachDB sqlalchemy](https://github.com/cockroachdb/sqlalchemy-cockroachdb)
141
+ - [RisingWave: Open-Source Streaming Database](https://www.risingwave.com/database/)
142
+ - [RisingWave Cloud](https://www.risingwave.com/cloud/)
143
+ - [What is RisingWave?](https://docs.risingwave.com/docs/current/intro/)
@@ -1,6 +1,7 @@
1
1
  [tool:pytest]
2
2
  addopts = --tb native -v -r fxX --maxfail=25 -p no:warnings
3
3
  python_files = test/*test_*.py
4
+ testpaths = test
4
5
 
5
6
  [sqla_testing]
6
7
  requirement_cls = sqlalchemy_risingwave.requirements:Requirements
@@ -23,11 +23,10 @@ setup(
23
23
  "License :: OSI Approved :: Apache Software License",
24
24
  "Programming Language :: Python :: 3",
25
25
  "Programming Language :: Python :: 3 :: Only",
26
- "Programming Language :: Python :: 3.8",
27
- "Programming Language :: Python :: 3.9",
28
26
  "Programming Language :: Python :: 3.10",
29
27
  "Programming Language :: Python :: 3.11",
30
28
  "Programming Language :: Python :: 3.12",
29
+ "Programming Language :: Python :: 3.13",
31
30
  ],
32
31
  keywords="SQLAlchemy RisingWave",
33
32
  project_urls={
@@ -36,7 +35,8 @@ setup(
36
35
  },
37
36
  packages=find_packages(include=["sqlalchemy_risingwave"]),
38
37
  include_package_data=True,
39
- install_requires=["SQLAlchemy>=1.4,<2.0"],
38
+ python_requires=">=3.10",
39
+ install_requires=["SQLAlchemy>=2.0,<2.1"],
40
40
  zip_safe=False,
41
41
  # # Do not support dialects now.
42
42
  entry_points={
@@ -1,6 +1,6 @@
1
1
  from sqlalchemy.dialects import registry as _registry
2
2
 
3
- __version__ = "1.4.1"
3
+ __version__ = "2.0.0"
4
4
 
5
5
  _registry.register(
6
6
  "risingwave.psycopg2",