eorm 0.1.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.
eorm/__init__.py ADDED
@@ -0,0 +1,17 @@
1
+ from eorm.engine import Engine, create_mysql_engine, create_postgresql_engine
2
+ from eorm.fields import Field
3
+ from eorm.model import Model
4
+ from eorm.row import Row
5
+ from eorm.session import Session, connect_mysql, connect_postgresql
6
+
7
+ __all__ = [
8
+ "Field",
9
+ "Model",
10
+ "Row",
11
+ "Session",
12
+ "Engine",
13
+ "connect_mysql",
14
+ "connect_postgresql",
15
+ "create_mysql_engine",
16
+ "create_postgresql_engine",
17
+ ]
eorm/ddl.py ADDED
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ import typing
4
+ from dataclasses import dataclass
5
+ from typing import Any
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class Index:
10
+ """索引定义,在 ``Meta.indexes`` 中声明。"""
11
+
12
+ fields: tuple[str, ...] # Python 属性名
13
+ unique: bool = False
14
+ name: str | None = None # None → 自动生成
15
+
16
+ def index_name(self, table: str) -> str:
17
+ """自动生成或返回显式索引名。"""
18
+ if self.name is not None:
19
+ return self.name
20
+ prefix = "unq" if self.unique else "ix"
21
+ fields_part = "_".join(self.fields)
22
+ return f"{prefix}_{table}_{fields_part}"
23
+
24
+
25
+ @dataclass
26
+ class IntrospectedColumn:
27
+ """Mirrors a single column row from INFORMATION_SCHEMA.COLUMNS."""
28
+
29
+ column_name: str
30
+ data_type: str
31
+ is_nullable: bool
32
+ column_default: str | None = None
33
+
34
+
35
+ def resolve_base_type(annotation: Any) -> type:
36
+ """Unwrap ``Optional[X]`` / ``X | None`` and parameterised generics.
37
+
38
+ ``Optional[str]`` → ``str``; ``dict[str, Any]`` → ``dict``.
39
+ """
40
+ args = typing.get_args(annotation)
41
+ if args:
42
+ non_none = [a for a in args if a is not type(None)]
43
+ if len(non_none) == 1:
44
+ return non_none[0]
45
+ origin = typing.get_origin(annotation)
46
+ if origin is not None:
47
+ return origin
48
+ return annotation
49
+
50
+
51
+ def is_optional(annotation: Any) -> bool:
52
+ """Return ``True`` if the annotation accepts ``None``."""
53
+ args = typing.get_args(annotation)
54
+ if args:
55
+ return type(None) in args
56
+ return False
File without changes