sqla-fancy-core 0.3.0__py3-none-any.whl → 1.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of sqla-fancy-core might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  """SQLAlchemy core, but fancier."""
2
2
 
3
- from typing import Optional, Union
3
+ from typing import Optional, Union, overload
4
4
 
5
5
  import sqlalchemy as sa
6
6
 
@@ -135,7 +135,25 @@ class TableFactory:
135
135
  def created_at(self, name="created_at", *args, **kwargs) -> sa.Column:
136
136
  return self.datetime(name, default=sa.func.now(), *args, **kwargs)
137
137
 
138
- def __call__(self, name, *args, **kwargs):
139
- cols = self.c
140
- self.c = []
141
- return sa.Table(name, self.metadata, *args, *cols, **kwargs)
138
+ @overload
139
+ def __call__(self, arg1: str, *args, **kwargs) -> sa.Table: ...
140
+ @overload
141
+ def __call__(self, arg1: sa.Column, *args, **kwargs) -> sa.Column: ...
142
+ @overload
143
+ def __call__(self, arg1: sa.Table, *args, **kwargs) -> sa.Table: ...
144
+ def __call__(self, arg1, *args, **kwargs):
145
+ if isinstance(arg1, str):
146
+ cols = self.c
147
+ self.c = []
148
+ return sa.Table(arg1, self.metadata, *args, *cols, **kwargs)
149
+ elif isinstance(arg1, sa.Column):
150
+ arg1.info["args"] = args
151
+ arg1.info["kwargs"] = kwargs
152
+ self.c.append(arg1)
153
+ return arg1
154
+ elif isinstance(arg1, sa.Table):
155
+ cols = self.c
156
+ self.c = []
157
+ return sa.Table(arg1.name, self.metadata, *args, *cols, **kwargs)
158
+ else:
159
+ raise TypeError(f"Expected a string or Column, got {type(arg1).__name__}")
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: sqla-fancy-core
3
- Version: 0.3.0
3
+ Version: 1.0.0
4
4
  Summary: SQLAlchemy core, but fancier
5
5
  Project-URL: Homepage, https://github.com/sayanarijit/sqla-fancy-core
6
6
  Author-email: Arijit Basu <sayanarijit@gmail.com>
@@ -28,19 +28,14 @@ License: MIT License
28
28
  SOFTWARE.
29
29
  License-File: LICENSE
30
30
  Keywords: sql,sqlalchemy,sqlalchemy-core
31
- Classifier: Development Status :: 3 - Alpha
32
31
  Classifier: Intended Audience :: Developers
33
32
  Classifier: License :: OSI Approved :: MIT License
34
33
  Classifier: Programming Language :: Python :: 3
35
- Classifier: Programming Language :: Python :: 3.7
36
- Classifier: Programming Language :: Python :: 3.8
37
- Classifier: Programming Language :: Python :: 3.9
38
- Classifier: Programming Language :: Python :: 3.10
39
- Classifier: Programming Language :: Python :: 3.11
40
34
  Requires-Python: >=3.7
41
35
  Requires-Dist: sqlalchemy
42
36
  Provides-Extra: test
43
37
  Requires-Dist: flake8; extra == 'test'
38
+ Requires-Dist: pydantic; extra == 'test'
44
39
  Requires-Dist: pytest; extra == 'test'
45
40
  Description-Content-Type: text/markdown
46
41
 
@@ -48,9 +43,10 @@ Description-Content-Type: text/markdown
48
43
 
49
44
  SQLAlchemy core, but fancier.
50
45
 
46
+ ### Basic Usage
47
+
51
48
  ```python
52
49
  import sqlalchemy as sa
53
-
54
50
  from sqla_fancy_core import TableFactory
55
51
 
56
52
  tf = TableFactory()
@@ -65,16 +61,62 @@ class Author:
65
61
 
66
62
  Table = tf("author")
67
63
 
68
- # Define a table
64
+ # Or define it without losing type hints
69
65
  class Book:
66
+ id = tf(sa.Column("id", sa.Integer, primary_key=True, autoincrement=True))
67
+ title = tf(sa.Column("title", sa.String(255), nullable=False))
68
+ author_id = tf(sa.Column("author_id", sa.Integer, sa.ForeignKey(Author.id)))
69
+ created_at = tf(
70
+ sa.Column(
71
+ "created_at",
72
+ sa.DateTime,
73
+ nullable=False,
74
+ server_default=sa.func.now(),
75
+ )
76
+ )
77
+ updated_at = tf(
78
+ sa.Column(
79
+ "updated_at",
80
+ sa.DateTime,
81
+ nullable=False,
82
+ server_default=sa.func.now(),
83
+ onupdate=sa.func.now(),
84
+ )
85
+ )
70
86
 
71
- id = tf.auto_id()
72
- title = tf.string("title")
73
- author_id = tf.foreign_key("author_id", Author.id)
74
- created_at = tf.created_at()
75
- updated_at = tf.updated_at()
87
+ Table = tf(sa.Table("book", sa.MetaData()))
76
88
 
77
- Table = tf("book")
89
+ # Create the tables
90
+ engine = sa.create_engine("sqlite:///:memory:")
91
+ tf.metadata.create_all(engine)
92
+
93
+ with engine.connect() as conn:
94
+ # Insert author
95
+ qry = (
96
+ sa.insert(Author.Table)
97
+ .values({Author.name: "John Doe"})
98
+ .returning(Author.id)
99
+ )
100
+ author = next(conn.execute(qry).mappings())
101
+ author_id = author[Author.id]
102
+ assert author_id == 1
103
+
104
+ # Insert book
105
+ qry = (
106
+ sa.insert(Book.Table)
107
+ .values({Book.title: "My Book", Book.author_id: author_id})
108
+ .returning(Book.id)
109
+ )
110
+ book = next(conn.execute(qry).mappings())
111
+ assert book[Book.id] == 1
112
+
113
+ # Query the data
114
+ qry = sa.select(Author.name, Book.title).join(
115
+ Book.Table,
116
+ Book.author_id == Author.id,
117
+ )
118
+ result = conn.execute(qry).fetchall()
119
+ assert result == [("John Doe", "My Book")], result
78
120
 
79
121
  # Create the tables
80
122
  engine = sa.create_engine("sqlite:///:memory:")
@@ -87,8 +129,8 @@ with engine.connect() as conn:
87
129
  .values({Author.name: "John Doe"})
88
130
  .returning(Author.id)
89
131
  )
90
- author = next(conn.execute(qry))
91
- author_id = author._mapping[Author.id]
132
+ author = next(conn.execute(qry).mappings())
133
+ author_id = author[Author.id]
92
134
  assert author_id == 1
93
135
 
94
136
  # Insert book
@@ -97,8 +139,8 @@ with engine.connect() as conn:
97
139
  .values({Book.title: "My Book", Book.author_id: author_id})
98
140
  .returning(Book.id)
99
141
  )
100
- book = next(conn.execute(qry))
101
- assert book._mapping[Book.id] == 1
142
+ book = next(conn.execute(qry).mappings())
143
+ assert book[Book.id] == 1
102
144
 
103
145
  # Query the data
104
146
  qry = sa.select(Author.name, Book.title).join(
@@ -108,3 +150,43 @@ with engine.connect() as conn:
108
150
  result = conn.execute(qry).fetchall()
109
151
  assert result == [("John Doe", "My Book")], result
110
152
  ```
153
+
154
+ ### With Pydantic Validation
155
+
156
+ ```python
157
+ from typing import Any
158
+ import sqlalchemy as sa
159
+ from pydantic import BaseModel, Field
160
+
161
+ from sqla_fancy_core import TableFactory
162
+
163
+ tf = TableFactory()
164
+
165
+ def field(col, default: Any = ...) -> Field:
166
+ return col.info["kwargs"]["field"](default)
167
+
168
+ # Define a table
169
+ class User:
170
+ name = tf(
171
+ sa.Column("name", sa.String),
172
+ field=lambda default: Field(default, max_length=5),
173
+ )
174
+ Table = tf("author")
175
+
176
+ # Define a pydantic schema
177
+ class CreateUser(BaseModel):
178
+ name: str = field(User.name)
179
+
180
+ # Define a pydantic schema
181
+ class UpdateUser(BaseModel):
182
+ name: str | None = field(User.name, None)
183
+
184
+ assert CreateUser(name="John").model_dump() == {"name": "John"}
185
+ assert UpdateUser(name="John").model_dump() == {"name": "John"}
186
+ assert UpdateUser().model_dump(exclude_unset=True) == {}
187
+
188
+ with pytest.raises(ValueError):
189
+ CreateUser()
190
+ with pytest.raises(ValueError):
191
+ UpdateUser(name="John Doe")
192
+ ```
@@ -0,0 +1,5 @@
1
+ sqla_fancy_core/__init__.py,sha256=GwPbjEPhM-mxFcsjZizCQ9dnUNgqBswCfwrI_u-JVfc,6376
2
+ sqla_fancy_core-1.0.0.dist-info/METADATA,sha256=1UBn6tJ7EK6TXKBdq6gUWtzStIqeHS3lsKDb9pkZBCE,5671
3
+ sqla_fancy_core-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
4
+ sqla_fancy_core-1.0.0.dist-info/licenses/LICENSE,sha256=XcYXJ0ipvwOn-nzko6p_xoCCbke8tAhmlIN04rUZDLk,1068
5
+ sqla_fancy_core-1.0.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.18.0
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,5 +0,0 @@
1
- sqla_fancy_core/__init__.py,sha256=GfDeOQ3yhk3IeTnEVTiZv4RQiYi69N-zpVl8Rn2fNyU,5616
2
- sqla_fancy_core-0.3.0.dist-info/METADATA,sha256=5B2vEXT-peD_v9ET0wInmBrw7nxhm32yd9NHxrmOXj8,3606
3
- sqla_fancy_core-0.3.0.dist-info/WHEEL,sha256=9QBuHhg6FNW7lppboF2vKVbCGTVzsFykgRQjjlajrhA,87
4
- sqla_fancy_core-0.3.0.dist-info/licenses/LICENSE,sha256=XcYXJ0ipvwOn-nzko6p_xoCCbke8tAhmlIN04rUZDLk,1068
5
- sqla_fancy_core-0.3.0.dist-info/RECORD,,