BatisX 2.2.1__tar.gz → 2.2.2__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.
@@ -1,165 +1,165 @@
1
- Metadata-Version: 2.1
2
- Name: batisx
3
- Version: 2.2.1
4
- Summary: A thread safe sql executor for Python like MyBatis with connection pool. It helps you automatically manage database connections and transactions. It also provides ORM operations for single tables.
5
- Home-page: https://gitee.com/summry/batisx
6
- Author: summy
7
- Author-email: xiazhongbiao@126.com
8
- License: UNKNOWN
9
- Keywords: sql,MySQL,PostgreSQL,MyBatis,python
10
- Platform: UNKNOWN
11
- Requires-Python: >=3.5
12
- Description-Content-Type: text/markdown
13
-
14
- Mapper file
15
- '''''''''''
16
-
17
- Create a mapper file in 'mapper' folder, you can named
18
- 'person_mapper.xml', like follow:
19
-
20
- .. code:: xml
21
-
22
- <?xml version="1.0" encoding="UTF-8"?>
23
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://gitee.com/summry/batisx/blob/master/dtd/mapper.dtd">
24
- <mapper namespace="person">
25
- <select id="select_all">
26
- select id, name, age from person
27
- </select>
28
-
29
- <select id="select_by_name">
30
- select id, name, age from person where name = ?
31
- </select>
32
-
33
- <select id="select_by_name2">
34
- select id, name, age from person where name = :name
35
- </select>
36
-
37
- <select id="select_include" include="select_all">
38
- {{ select_all }}
39
- {% if name -%}
40
- where name = :name
41
- {%- endif -%}
42
- </select>
43
- </mapper>
44
-
45
- Usage Sample
46
- ''''''''''''
47
-
48
- .. code:: python
49
-
50
- from typing import List, Tuple, Mapping
51
- from batisx import mapper, sql, dbx, init_db
52
-
53
- @mapper(namespace='person')
54
- def select_all(): List
55
-
56
- @mapper(namespace='person')
57
- def select_by_name(name: str): List
58
-
59
- @mapper(namespace='person')
60
- def select_by_name2(name: str): List
61
-
62
- @mapper(namespace='person')
63
- def select_include(name: str): List
64
-
65
- @sql('select id, name, age from person where name = ?')
66
- def query_by_name(name: str): List(Mapping)
67
-
68
- @sql('select id, name, age from person where name = :name')
69
- def query_by_name2(name: str): List(Mapping)
70
-
71
- if __name__ == '__main__':
72
- # init_db('test.db', driver='sqlite3', show_sql=True, debug=True, mapper_path='./mapper')
73
- # init_db("postgres://user:password@127.0.0.1:5432/testdb", driver='psycopg2', pool_size=5, mapper_path='./mapper')
74
- init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
75
-
76
- persons = select_all()
77
- # result:
78
- # (3, 'zhangsan', 15)
79
- # (4, 'lisi', 26)
80
- # (5, 'wangwu', 38)
81
-
82
- persons = select_by_name('zhangsan')
83
- # result:
84
- # (3, 'zhangsan', 15)
85
-
86
- persons = select_by_name2(name='zhangsan')
87
- # result:
88
- # (3, 'zhangsan', 15)
89
-
90
- persons = select_include(name='zhangsan')
91
- # result:
92
- # (3, 'zhangsan', 15)
93
-
94
- persons = query_by_name('zhangsan')
95
- # result:
96
- # {'id': 3, 'name': 'zhangsan', 'age': 15}
97
-
98
- persons = query_by_name2(name='zhangsan')
99
- # result:
100
- # {'id': 3, 'name': 'zhangsan', 'age': 15}
101
-
102
- # you can use dbx execute mapper sql with full sql id: namespace join sql id
103
- persons = dbx.select('person.select_all') # 'person' is namespace, 'select_all' is sql id
104
- # result:
105
- # (3, 'zhangsan', 15)
106
- # (4, 'lisi', 26)
107
- # (5, 'wangwu', 38)
108
-
109
- persons = dbx.select('person.select_by_name', name='zhangsan')
110
- # result:
111
- # (3, 'zhangsan', 15)
112
-
113
- persons = dbx.sql('person.select_by_name').select(name='zhangsan')
114
- # result:
115
- # (3, 'zhangsan', 15)
116
-
117
- # you can direct execute sql with db
118
- effected_rowcount = db.insert(table='person', name='zhaoliu', age=66)
119
-
120
- persons = db.select('select id, name, age from person')
121
- # result:
122
- # (3, 'zhangsan', 15)
123
- # (4, 'lisi', 26)
124
- # (5, 'wangwu', 38)
125
- # (6, 'zhaoliu', 45)
126
-
127
- persons = db.query('select id, name, age from person name = :name', name='zhangsan')
128
- # result:
129
- # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
130
-
131
- persons = db.sql('select id, name, age from person name = :name').query(name='zhangsan')
132
- # result:
133
- # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
134
-
135
- persons = db.select('select id, name, age from person where name = ?', 'zhangsan')
136
- # result:
137
- # [(3, 'zhangsan', 15)]
138
-
139
-
140
- Transaction
141
- '''''''''''
142
-
143
- .. code:: python
144
-
145
- from batisx import with_transaction, transaction
146
-
147
- @with_transaction
148
- def test_transaction():
149
- insert_func(....)
150
- update_func(....)
151
-
152
-
153
- def test_transaction2():
154
- with transaction():
155
- insert_func(....)
156
- update_func(....)
157
-
158
-
159
- If you want to operate MySQL database, may be you need MySqlx: https://pypi.org/project/mysqlx
160
-
161
- If you want to operate PostgreSQL database, may be you need MySqlx: https://pypi.org/project/pgsqlx
162
-
163
- If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlx-exec
164
-
165
-
1
+ Metadata-Version: 2.1
2
+ Name: batisx
3
+ Version: 2.2.2
4
+ Summary: A thread safe sql executor for Python like MyBatis with connection pool. It helps you automatically manage database connections and transactions. It also provides ORM operations for single tables.
5
+ Home-page: https://gitee.com/summry/batisx
6
+ Author: summy
7
+ Author-email: xiazhongbiao@126.com
8
+ License: UNKNOWN
9
+ Keywords: sql,MySQL,PostgreSQL,MyBatis,python
10
+ Platform: UNKNOWN
11
+ Requires-Python: >=3.5
12
+ Description-Content-Type: text/markdown
13
+
14
+ Mapper file
15
+ '''''''''''
16
+
17
+ Create a mapper file in 'mapper' folder, you can named
18
+ 'person_mapper.xml', like follow:
19
+
20
+ .. code:: xml
21
+
22
+ <?xml version="1.0" encoding="UTF-8"?>
23
+ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://gitee.com/summry/batisx/blob/master/dtd/mapper.dtd">
24
+ <mapper namespace="person">
25
+ <select id="select_all">
26
+ select id, name, age from person
27
+ </select>
28
+
29
+ <select id="select_by_name">
30
+ select id, name, age from person where name = ?
31
+ </select>
32
+
33
+ <select id="select_by_name2">
34
+ select id, name, age from person where name = :name
35
+ </select>
36
+
37
+ <select id="select_include" include="select_all">
38
+ {{ select_all }}
39
+ {% if name -%}
40
+ where name = :name
41
+ {%- endif -%}
42
+ </select>
43
+ </mapper>
44
+
45
+ Usage Sample
46
+ ''''''''''''
47
+
48
+ .. code:: python
49
+
50
+ from typing import List, Tuple, Mapping
51
+ from batisx import mapper, sql, dbx, init_db
52
+
53
+ @mapper(namespace='person')
54
+ def select_all(): List
55
+
56
+ @mapper(namespace='person')
57
+ def select_by_name(name: str): List
58
+
59
+ @mapper(namespace='person')
60
+ def select_by_name2(name: str): List
61
+
62
+ @mapper(namespace='person')
63
+ def select_include(name: str): List
64
+
65
+ @sql('select id, name, age from person where name = ?')
66
+ def query_by_name(name: str): List(Mapping)
67
+
68
+ @sql('select id, name, age from person where name = :name')
69
+ def query_by_name2(name: str): List(Mapping)
70
+
71
+ if __name__ == '__main__':
72
+ # init_db('test.db', driver='sqlite3', show_sql=True, debug=True, mapper_path='./mapper')
73
+ # init_db("postgres://user:password@127.0.0.1:5432/testdb", driver='psycopg2', pool_size=5, mapper_path='./mapper')
74
+ init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
75
+
76
+ persons = select_all()
77
+ # result:
78
+ # (3, 'zhangsan', 15)
79
+ # (4, 'lisi', 26)
80
+ # (5, 'wangwu', 38)
81
+
82
+ persons = select_by_name('zhangsan')
83
+ # result:
84
+ # (3, 'zhangsan', 15)
85
+
86
+ persons = select_by_name2(name='zhangsan')
87
+ # result:
88
+ # (3, 'zhangsan', 15)
89
+
90
+ persons = select_include(name='zhangsan')
91
+ # result:
92
+ # (3, 'zhangsan', 15)
93
+
94
+ persons = query_by_name('zhangsan')
95
+ # result:
96
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
97
+
98
+ persons = query_by_name2(name='zhangsan')
99
+ # result:
100
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
101
+
102
+ # you can use dbx execute mapper sql with full sql id: namespace join sql id
103
+ persons = dbx.select('person.select_all') # 'person' is namespace, 'select_all' is sql id
104
+ # result:
105
+ # (3, 'zhangsan', 15)
106
+ # (4, 'lisi', 26)
107
+ # (5, 'wangwu', 38)
108
+
109
+ persons = dbx.select('person.select_by_name', name='zhangsan')
110
+ # result:
111
+ # (3, 'zhangsan', 15)
112
+
113
+ persons = dbx.sql('person.select_by_name').select(name='zhangsan')
114
+ # result:
115
+ # (3, 'zhangsan', 15)
116
+
117
+ # you can direct execute sql with db
118
+ effected_rowcount = db.insert(table='person', name='zhaoliu', age=66)
119
+
120
+ persons = db.select('select id, name, age from person')
121
+ # result:
122
+ # (3, 'zhangsan', 15)
123
+ # (4, 'lisi', 26)
124
+ # (5, 'wangwu', 38)
125
+ # (6, 'zhaoliu', 45)
126
+
127
+ persons = db.query('select id, name, age from person name = :name', name='zhangsan')
128
+ # result:
129
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
130
+
131
+ persons = db.sql('select id, name, age from person name = :name').query(name='zhangsan')
132
+ # result:
133
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
134
+
135
+ persons = db.select('select id, name, age from person where name = ?', 'zhangsan')
136
+ # result:
137
+ # [(3, 'zhangsan', 15)]
138
+
139
+
140
+ Transaction
141
+ '''''''''''
142
+
143
+ .. code:: python
144
+
145
+ from batisx import with_transaction, transaction
146
+
147
+ @with_transaction
148
+ def test_transaction():
149
+ insert_func(....)
150
+ update_func(....)
151
+
152
+
153
+ def test_transaction2():
154
+ with transaction():
155
+ insert_func(....)
156
+ update_func(....)
157
+
158
+
159
+ If you want to operate MySQL database, may be you need MySqlx: https://pypi.org/project/mysqlx
160
+
161
+ If you want to operate PostgreSQL database, may be you need MySqlx: https://pypi.org/project/pgsqlx
162
+
163
+ If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlexecx
164
+
165
+
@@ -147,4 +147,4 @@ If you want to operate MySQL database, may be you need MySqlx: https://pypi.org/
147
147
 
148
148
  If you want to operate PostgreSQL database, may be you need MySqlx: https://pypi.org/project/pgsqlx
149
149
 
150
- If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlx-exec
150
+ If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlexecx
@@ -1,13 +1,13 @@
1
- from mysqlx import (
2
- connection,
3
- transaction,
4
- with_connection,
5
- with_transaction,
6
- get_connection,
7
- close,
8
- Driver,
9
- Dialect,
10
- init_db
11
- )
12
- from .sql_mapper import sql, mapper
13
-
1
+ from mysqlx import (
2
+ connection,
3
+ transaction,
4
+ with_connection,
5
+ with_transaction,
6
+ get_connection,
7
+ close,
8
+ Driver,
9
+ Dialect,
10
+ init_db
11
+ )
12
+ from .sql_mapper import sql, mapper
13
+
@@ -1,33 +1,33 @@
1
- from mysqlx import sql_support
2
- # Don't remove. Import for not repetitive implementation
3
- from sqlexecx import save_select_key, do_save_sql_select_key
4
- from mysqlx.db import insert, save, execute, batch_insert, batch_execute, get, query, query_one, select, select_one, \
5
- do_execute, do_get, do_query, do_query_one, do_select, do_select_one, do_select_page, do_query_page, select_page, query_page,\
6
- do_save_sql, drop_table, truncate_table, sql, table, page
7
-
8
-
9
- def save_sql(sql: str, *args, **kwargs):
10
- """
11
- Insert data into table, return primary key.
12
- :param select_key: sql for select primary key
13
- :param sql: SQL
14
- :param args:
15
- :return: Primary key
16
- """
17
- sql, args = sql_support.try_dynamic_sql('batisx.db.save_sql', sql, *args, **kwargs)
18
- return do_save_sql(sql, *args)
19
-
20
-
21
- def save_sql_select_key(select_key: str, sql: str, *args, **kwargs):
22
- """
23
- Insert data into table, return primary key.
24
- :param select_key: sql for select primary key
25
- :param sql: SQL
26
- :param args:
27
- :return: Primary key
28
- """
29
- sql, args = sql_support.try_dynamic_sql('batisx.db.save_sql', sql, *args, **kwargs)
30
- return do_save_sql_select_key(select_key, sql, *args)
31
-
32
-
33
- from .sql_page_exec import sql, page
1
+ from mysqlx import sql_support
2
+ # Don't remove. Import for not repetitive implementation
3
+ from sqlexecx import save_select_key, do_save_sql_select_key
4
+ from mysqlx.db import insert, save, execute, batch_insert, batch_execute, get, query, query_one, select, select_one, \
5
+ do_execute, do_get, do_query, do_query_one, do_select, do_select_one, do_select_page, do_query_page, select_page, query_page,\
6
+ do_save_sql, drop_table, truncate_table, sql, table, page
7
+
8
+
9
+ def save_sql(sql: str, *args, **kwargs):
10
+ """
11
+ Insert data into table, return primary key.
12
+ :param select_key: sql for select primary key
13
+ :param sql: SQL
14
+ :param args:
15
+ :return: Primary key
16
+ """
17
+ sql, args = sql_support.try_dynamic_sql('batisx.db.save_sql', sql, *args, **kwargs)
18
+ return do_save_sql(sql, *args)
19
+
20
+
21
+ def save_sql_select_key(select_key: str, sql: str, *args, **kwargs):
22
+ """
23
+ Insert data into table, return primary key.
24
+ :param select_key: sql for select primary key
25
+ :param sql: SQL
26
+ :param args:
27
+ :return: Primary key
28
+ """
29
+ sql, args = sql_support.try_dynamic_sql('batisx.db.save_sql', sql, *args, **kwargs)
30
+ return do_save_sql_select_key(select_key, sql, *args)
31
+
32
+
33
+ from .sql_page_exec import sql, page
@@ -1,32 +1,32 @@
1
- from mysqlx import sql_holder as holder
2
- from mysqlx.dbx import batch_execute, execute, get, query, query_one, select, select_one, select_page, query_page, sql, page
3
-
4
- from . import db
5
- from .log_support import logger, sql_id_log, page_sql_id_log, sql_id_select_key_log
6
-
7
-
8
- def save(sql_id: str, *args, **kwargs):
9
- """
10
- Execute insert SQL, return primary key.
11
- :return: Primary key
12
- """
13
- sql_id_log('save', sql_id, *args, **kwargs)
14
- sql_model = holder.get_sql_model(sql_id)
15
- select_key = sql_model.select_key
16
- sql, args = holder.do_get_sql(sql_model, False, None, *args, **kwargs)
17
- if select_key:
18
- return db.do_save_sql_select_key(select_key, sql, *args)
19
- return db.do_save_sql(sql, *args)
20
-
21
-
22
- def save_select_key(select_key, sql_id: str, *args, **kwargs):
23
- """
24
- Execute insert SQL, return primary key.
25
- :return: Primary key
26
- """
27
- sql_id_select_key_log('save_select_key', select_key, sql_id, *args, **kwargs)
28
- sql, args = holder.get_sql(sql_id, *args, **kwargs)
29
- return db.do_save_sql_select_key(select_key, sql, *args)
30
-
31
-
32
- from .sql_id_exec import sql, page
1
+ from mysqlx import sql_holder as holder
2
+ from mysqlx.dbx import batch_execute, execute, get, query, query_one, select, select_one, select_page, query_page, sql, page
3
+
4
+ from . import db
5
+ from .log_support import logger, sql_id_log, page_sql_id_log, sql_id_select_key_log
6
+
7
+
8
+ def save(sql_id: str, *args, **kwargs):
9
+ """
10
+ Execute insert SQL, return primary key.
11
+ :return: Primary key
12
+ """
13
+ sql_id_log('save', sql_id, *args, **kwargs)
14
+ sql_model = holder.get_sql_model(sql_id)
15
+ select_key = sql_model.select_key
16
+ sql, args = holder.do_get_sql(sql_model, False, None, *args, **kwargs)
17
+ if select_key:
18
+ return db.do_save_sql_select_key(select_key, sql, *args)
19
+ return db.do_save_sql(sql, *args)
20
+
21
+
22
+ def save_select_key(select_key, sql_id: str, *args, **kwargs):
23
+ """
24
+ Execute insert SQL, return primary key.
25
+ :return: Primary key
26
+ """
27
+ sql_id_select_key_log('save_select_key', select_key, sql_id, *args, **kwargs)
28
+ sql, args = holder.get_sql(sql_id, *args, **kwargs)
29
+ return db.do_save_sql_select_key(select_key, sql, *args)
30
+
31
+
32
+ from .sql_id_exec import sql, page
@@ -1,13 +1,13 @@
1
- from mysqlx.log_support import logger
2
-
3
-
4
- def page_sql_id_log(function: str, sql_id: str, page_num, page_size, *args, **kwargs):
5
- logger.debug("Exec func 'batisx.dbx.%s', page_num: %d, page_size: %d, sql_id: %s, args: %s, kwargs: %s" % (function, page_num, page_size, sql_id, args, kwargs))
6
-
7
-
8
- def sql_id_log(function: str, sql_id: str, *args, **kwargs):
9
- logger.debug("Exec func '%s', sql_id: %s, args: %s, kwargs: %s" % (function, sql_id.strip(), args, kwargs))
10
-
11
-
12
- def sql_id_select_key_log(function: str, select_key: str, sql_id: str, *args, **kwargs):
13
- logger.debug("Exec func 'batisx.dbx.%s', select_key: %s, sql_id: %s, args: %s, kwargs: %s" % (function, select_key, sql_id.strip(), args, kwargs))
1
+ from mysqlx.log_support import logger
2
+
3
+
4
+ def page_sql_id_log(function: str, sql_id: str, page_num, page_size, *args, **kwargs):
5
+ logger.debug("Exec func 'batisx.dbx.%s', page_num: %d, page_size: %d, sql_id: %s, args: %s, kwargs: %s" % (function, page_num, page_size, sql_id, args, kwargs))
6
+
7
+
8
+ def sql_id_log(function: str, sql_id: str, *args, **kwargs):
9
+ logger.debug("Exec func '%s', sql_id: %s, args: %s, kwargs: %s" % (function, sql_id.strip(), args, kwargs))
10
+
11
+
12
+ def sql_id_select_key_log(function: str, select_key: str, sql_id: str, *args, **kwargs):
13
+ logger.debug("Exec func 'batisx.dbx.%s', select_key: %s, sql_id: %s, args: %s, kwargs: %s" % (function, select_key, sql_id.strip(), args, kwargs))
@@ -1,25 +1,25 @@
1
- from . import dbx
2
- from mysqlx.sql_id_exec import SqlExec as _SqlExec
3
- from sqlexecx.page_exec import PageExec
4
-
5
-
6
- class SqlExec(_SqlExec):
7
-
8
- def save_select_key(self, select_key: str, *args, **kwargs):
9
- """
10
- Insert data into table, return primary key.
11
-
12
- :param select_key: sql for select primary key
13
- :param args:
14
- :return: Primary key
15
- """
16
- return self.exec.save_select_key(select_key, self.sql, *args, **kwargs)
17
-
18
-
19
- def sql(sql: str) :
20
- assert sql, "Parameter 'sql' must not be none"
21
- return SqlExec(dbx, sql)
22
-
23
-
24
- def page(page_num: int, page_size: int) :
25
- return PageExec(dbx, page_num, page_size)
1
+ from . import dbx
2
+ from mysqlx.sql_id_exec import SqlExec as _SqlExec
3
+ from sqlexecx.page_exec import PageExec
4
+
5
+
6
+ class SqlExec(_SqlExec):
7
+
8
+ def save_select_key(self, select_key: str, *args, **kwargs):
9
+ """
10
+ Insert data into table, return primary key.
11
+
12
+ :param select_key: sql for select primary key
13
+ :param args:
14
+ :return: Primary key
15
+ """
16
+ return self.exec.save_select_key(select_key, self.sql, *args, **kwargs)
17
+
18
+
19
+ def sql(sql: str) :
20
+ assert sql, "Parameter 'sql' must not be none"
21
+ return SqlExec(dbx, sql)
22
+
23
+
24
+ def page(page_num: int, page_size: int) :
25
+ return PageExec(dbx, page_num, page_size)
@@ -1,82 +1,82 @@
1
- import os
2
- import sqlexecx
3
- import functools
4
- from .log_support import logger
5
- from mysqlx.support import SqlAction, DBError
6
- from mysqlx.sql_support import simple_sql, get_named_sql_args
7
- from mysqlx.sql_holder import get_sql_model, do_get_sql, build_sql_id
8
- from mysqlx.sql_mapper import get_exec_func, get_select_func, before
9
-
10
- _UPDATE_ACTIONS = (SqlAction.INSERT.value, SqlAction.UPDATE.value, SqlAction.DELETE.value, SqlAction.CALL.value)
11
-
12
-
13
- def mapper(namespace: str = None, sql_id: str = None, batch=False, return_key=False, select_key=None):
14
- def _decorator(func):
15
- @functools.wraps(func)
16
- def _wrapper(*args, **kwargs):
17
- param_names = func.__code__.co_varnames
18
- full_sql_id, func_name = before(func, namespace, sql_id, *args, **kwargs)
19
- sql_model = get_sql_model(full_sql_id)
20
- exec_func = get_exec_func(func, sql_model.action, batch)
21
- if return_key:
22
- use_select_key = select_key
23
- use_sql, args = do_get_sql(sql_model, batch, param_names, *args, **kwargs)
24
- if use_select_key is None:
25
- use_select_key = sql_model.select_key
26
- if use_select_key is None:
27
- try:
28
- use_select_key = sqlexecx.Dialect.get_select_key(sql=use_sql)
29
- except NotImplementedError:
30
- return DBError(
31
- f"Expect 'select_key' but not. you can set it in mapper file with 'selectKey', or @mapper with 'select_key'")
32
- return sqlexecx.do_save_sql_select_key(use_select_key, use_sql, *args)
33
- if batch:
34
- if kwargs:
35
- logger.warning("Batch exec sql better use like '{}(args)' or '{}(*args)' then '{}(args=args)'".format(func_name, func_name, func_name))
36
- args = list(kwargs.values())[0]
37
- use_sql, _ = do_get_sql(sql_model, batch, param_names, *args)
38
- else:
39
- use_sql, args = do_get_sql(sql_model, batch, param_names, *args, **kwargs)
40
- return exec_func(use_sql, *args)
41
-
42
- return _wrapper
43
-
44
- return _decorator
45
-
46
-
47
- def sql(value: str, batch=False, return_key=False, select_key=None):
48
- def _decorator(func):
49
- @functools.wraps(func)
50
- def _wrapper(*args, **kwargs):
51
- use_sql = value
52
- low_sql = value.lower()
53
- if any([action in low_sql for action in _UPDATE_ACTIONS]):
54
- if batch:
55
- if kwargs:
56
- args = list(kwargs.values())[0]
57
- return sqlexecx.batch_execute(use_sql, *args)
58
- if return_key:
59
- use_select_key = select_key
60
- if use_select_key is None:
61
- try:
62
- use_select_key = sqlexecx.Dialect.get_select_key(sql=use_sql)
63
- except NotImplementedError:
64
- return DBError(f"Expect 'select_key' but not in func '{func.__name__}' at file: '{func.__code__.co_filename}', line {func.__code__.co_firstlineno}. you can set it @sql with 'select_key'")
65
- assert SqlAction.INSERT.value in low_sql, 'Only insert sql can return primary key.'
66
- if kwargs:
67
- use_sql, args = get_named_sql_args(use_sql, **kwargs)
68
- return sqlexecx.do_save_sql_select_key(use_select_key, use_sql, *args)
69
-
70
- if kwargs:
71
- use_sql, args = get_named_sql_args(use_sql, **kwargs)
72
- return sqlexecx.do_execute(use_sql, *args)
73
- elif SqlAction.SELECT.value in low_sql:
74
- select_func = get_select_func(func)
75
- use_sql, args = simple_sql(use_sql, *args, **kwargs)
76
- return select_func(use_sql, *args)
77
- else:
78
- return ValueError("Invalid sql: {}.".format(sql))
79
-
80
- return _wrapper
81
-
82
- return _decorator
1
+ import os
2
+ import sqlexecx
3
+ import functools
4
+ from .log_support import logger
5
+ from mysqlx.support import SqlAction, DBError
6
+ from mysqlx.sql_support import simple_sql, get_named_sql_args
7
+ from mysqlx.sql_holder import get_sql_model, do_get_sql, build_sql_id
8
+ from mysqlx.sql_mapper import get_exec_func, get_select_func, before
9
+
10
+ _UPDATE_ACTIONS = (SqlAction.INSERT.value, SqlAction.UPDATE.value, SqlAction.DELETE.value, SqlAction.CALL.value)
11
+
12
+
13
+ def mapper(namespace: str = None, sql_id: str = None, batch=False, return_key=False, select_key=None):
14
+ def _decorator(func):
15
+ @functools.wraps(func)
16
+ def _wrapper(*args, **kwargs):
17
+ param_names = func.__code__.co_varnames
18
+ full_sql_id, func_name = before(func, namespace, sql_id, *args, **kwargs)
19
+ sql_model = get_sql_model(full_sql_id)
20
+ exec_func = get_exec_func(func, sql_model.action, batch)
21
+ if return_key:
22
+ use_select_key = select_key
23
+ use_sql, args = do_get_sql(sql_model, batch, param_names, *args, **kwargs)
24
+ if use_select_key is None:
25
+ use_select_key = sql_model.select_key
26
+ if use_select_key is None:
27
+ try:
28
+ use_select_key = sqlexecx.Dialect.get_select_key(sql=use_sql)
29
+ except NotImplementedError:
30
+ return DBError(
31
+ f"Expect 'select_key' but not. you can set it in mapper file with 'selectKey', or @mapper with 'select_key'")
32
+ return sqlexecx.do_save_sql_select_key(use_select_key, use_sql, *args)
33
+ if batch:
34
+ if kwargs:
35
+ logger.warning("Batch exec sql better use like '{}(args)' or '{}(*args)' then '{}(args=args)'".format(func_name, func_name, func_name))
36
+ args = list(kwargs.values())[0]
37
+ use_sql, _ = do_get_sql(sql_model, batch, param_names, *args)
38
+ else:
39
+ use_sql, args = do_get_sql(sql_model, batch, param_names, *args, **kwargs)
40
+ return exec_func(use_sql, *args)
41
+
42
+ return _wrapper
43
+
44
+ return _decorator
45
+
46
+
47
+ def sql(value: str, batch=False, return_key=False, select_key=None):
48
+ def _decorator(func):
49
+ @functools.wraps(func)
50
+ def _wrapper(*args, **kwargs):
51
+ use_sql = value
52
+ low_sql = value.lower()
53
+ if any([action in low_sql for action in _UPDATE_ACTIONS]):
54
+ if batch:
55
+ if kwargs:
56
+ args = list(kwargs.values())[0]
57
+ return sqlexecx.batch_execute(use_sql, *args)
58
+ if return_key:
59
+ use_select_key = select_key
60
+ if use_select_key is None:
61
+ try:
62
+ use_select_key = sqlexecx.Dialect.get_select_key(sql=use_sql)
63
+ except NotImplementedError:
64
+ return DBError(f"Expect 'select_key' but not in func '{func.__name__}' at file: '{func.__code__.co_filename}', line {func.__code__.co_firstlineno}. you can set it @sql with 'select_key'")
65
+ assert SqlAction.INSERT.value in low_sql, 'Only insert sql can return primary key.'
66
+ if kwargs:
67
+ use_sql, args = get_named_sql_args(use_sql, **kwargs)
68
+ return sqlexecx.do_save_sql_select_key(use_select_key, use_sql, *args)
69
+
70
+ if kwargs:
71
+ use_sql, args = get_named_sql_args(use_sql, **kwargs)
72
+ return sqlexecx.do_execute(use_sql, *args)
73
+ elif SqlAction.SELECT.value in low_sql:
74
+ select_func = get_select_func(func)
75
+ use_sql, args = simple_sql(use_sql, *args, **kwargs)
76
+ return select_func(use_sql, *args)
77
+ else:
78
+ return ValueError("Invalid sql: {}.".format(sql))
79
+
80
+ return _wrapper
81
+
82
+ return _decorator
@@ -1,12 +1,12 @@
1
- from . import db
2
- from sqlexecx.sql_exec import SqlExec
3
- from sqlexecx.page_exec import PageExec
4
-
5
-
6
- def sql(sql: str) :
7
- assert sql, "Parameter 'sql' must not be none"
8
- return SqlExec(db, sql)
9
-
10
-
11
- def page(page_num: int, page_size: int) :
12
- return PageExec(db, page_num, page_size)
1
+ from . import db
2
+ from sqlexecx.sql_exec import SqlExec
3
+ from sqlexecx.page_exec import PageExec
4
+
5
+
6
+ def sql(sql: str) :
7
+ assert sql, "Parameter 'sql' must not be none"
8
+ return SqlExec(db, sql)
9
+
10
+
11
+ def page(page_num: int, page_size: int) :
12
+ return PageExec(db, page_num, page_size)
@@ -1,165 +1,165 @@
1
- Metadata-Version: 2.1
2
- Name: batisx
3
- Version: 2.2.1
4
- Summary: A thread safe sql executor for Python like MyBatis with connection pool. It helps you automatically manage database connections and transactions. It also provides ORM operations for single tables.
5
- Home-page: https://gitee.com/summry/batisx
6
- Author: summy
7
- Author-email: xiazhongbiao@126.com
8
- License: UNKNOWN
9
- Keywords: sql,MySQL,PostgreSQL,MyBatis,python
10
- Platform: UNKNOWN
11
- Requires-Python: >=3.5
12
- Description-Content-Type: text/markdown
13
-
14
- Mapper file
15
- '''''''''''
16
-
17
- Create a mapper file in 'mapper' folder, you can named
18
- 'person_mapper.xml', like follow:
19
-
20
- .. code:: xml
21
-
22
- <?xml version="1.0" encoding="UTF-8"?>
23
- <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://gitee.com/summry/batisx/blob/master/dtd/mapper.dtd">
24
- <mapper namespace="person">
25
- <select id="select_all">
26
- select id, name, age from person
27
- </select>
28
-
29
- <select id="select_by_name">
30
- select id, name, age from person where name = ?
31
- </select>
32
-
33
- <select id="select_by_name2">
34
- select id, name, age from person where name = :name
35
- </select>
36
-
37
- <select id="select_include" include="select_all">
38
- {{ select_all }}
39
- {% if name -%}
40
- where name = :name
41
- {%- endif -%}
42
- </select>
43
- </mapper>
44
-
45
- Usage Sample
46
- ''''''''''''
47
-
48
- .. code:: python
49
-
50
- from typing import List, Tuple, Mapping
51
- from batisx import mapper, sql, dbx, init_db
52
-
53
- @mapper(namespace='person')
54
- def select_all(): List
55
-
56
- @mapper(namespace='person')
57
- def select_by_name(name: str): List
58
-
59
- @mapper(namespace='person')
60
- def select_by_name2(name: str): List
61
-
62
- @mapper(namespace='person')
63
- def select_include(name: str): List
64
-
65
- @sql('select id, name, age from person where name = ?')
66
- def query_by_name(name: str): List(Mapping)
67
-
68
- @sql('select id, name, age from person where name = :name')
69
- def query_by_name2(name: str): List(Mapping)
70
-
71
- if __name__ == '__main__':
72
- # init_db('test.db', driver='sqlite3', show_sql=True, debug=True, mapper_path='./mapper')
73
- # init_db("postgres://user:password@127.0.0.1:5432/testdb", driver='psycopg2', pool_size=5, mapper_path='./mapper')
74
- init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
75
-
76
- persons = select_all()
77
- # result:
78
- # (3, 'zhangsan', 15)
79
- # (4, 'lisi', 26)
80
- # (5, 'wangwu', 38)
81
-
82
- persons = select_by_name('zhangsan')
83
- # result:
84
- # (3, 'zhangsan', 15)
85
-
86
- persons = select_by_name2(name='zhangsan')
87
- # result:
88
- # (3, 'zhangsan', 15)
89
-
90
- persons = select_include(name='zhangsan')
91
- # result:
92
- # (3, 'zhangsan', 15)
93
-
94
- persons = query_by_name('zhangsan')
95
- # result:
96
- # {'id': 3, 'name': 'zhangsan', 'age': 15}
97
-
98
- persons = query_by_name2(name='zhangsan')
99
- # result:
100
- # {'id': 3, 'name': 'zhangsan', 'age': 15}
101
-
102
- # you can use dbx execute mapper sql with full sql id: namespace join sql id
103
- persons = dbx.select('person.select_all') # 'person' is namespace, 'select_all' is sql id
104
- # result:
105
- # (3, 'zhangsan', 15)
106
- # (4, 'lisi', 26)
107
- # (5, 'wangwu', 38)
108
-
109
- persons = dbx.select('person.select_by_name', name='zhangsan')
110
- # result:
111
- # (3, 'zhangsan', 15)
112
-
113
- persons = dbx.sql('person.select_by_name').select(name='zhangsan')
114
- # result:
115
- # (3, 'zhangsan', 15)
116
-
117
- # you can direct execute sql with db
118
- effected_rowcount = db.insert(table='person', name='zhaoliu', age=66)
119
-
120
- persons = db.select('select id, name, age from person')
121
- # result:
122
- # (3, 'zhangsan', 15)
123
- # (4, 'lisi', 26)
124
- # (5, 'wangwu', 38)
125
- # (6, 'zhaoliu', 45)
126
-
127
- persons = db.query('select id, name, age from person name = :name', name='zhangsan')
128
- # result:
129
- # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
130
-
131
- persons = db.sql('select id, name, age from person name = :name').query(name='zhangsan')
132
- # result:
133
- # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
134
-
135
- persons = db.select('select id, name, age from person where name = ?', 'zhangsan')
136
- # result:
137
- # [(3, 'zhangsan', 15)]
138
-
139
-
140
- Transaction
141
- '''''''''''
142
-
143
- .. code:: python
144
-
145
- from batisx import with_transaction, transaction
146
-
147
- @with_transaction
148
- def test_transaction():
149
- insert_func(....)
150
- update_func(....)
151
-
152
-
153
- def test_transaction2():
154
- with transaction():
155
- insert_func(....)
156
- update_func(....)
157
-
158
-
159
- If you want to operate MySQL database, may be you need MySqlx: https://pypi.org/project/mysqlx
160
-
161
- If you want to operate PostgreSQL database, may be you need MySqlx: https://pypi.org/project/pgsqlx
162
-
163
- If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlx-exec
164
-
165
-
1
+ Metadata-Version: 2.1
2
+ Name: batisx
3
+ Version: 2.2.2
4
+ Summary: A thread safe sql executor for Python like MyBatis with connection pool. It helps you automatically manage database connections and transactions. It also provides ORM operations for single tables.
5
+ Home-page: https://gitee.com/summry/batisx
6
+ Author: summy
7
+ Author-email: xiazhongbiao@126.com
8
+ License: UNKNOWN
9
+ Keywords: sql,MySQL,PostgreSQL,MyBatis,python
10
+ Platform: UNKNOWN
11
+ Requires-Python: >=3.5
12
+ Description-Content-Type: text/markdown
13
+
14
+ Mapper file
15
+ '''''''''''
16
+
17
+ Create a mapper file in 'mapper' folder, you can named
18
+ 'person_mapper.xml', like follow:
19
+
20
+ .. code:: xml
21
+
22
+ <?xml version="1.0" encoding="UTF-8"?>
23
+ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://gitee.com/summry/batisx/blob/master/dtd/mapper.dtd">
24
+ <mapper namespace="person">
25
+ <select id="select_all">
26
+ select id, name, age from person
27
+ </select>
28
+
29
+ <select id="select_by_name">
30
+ select id, name, age from person where name = ?
31
+ </select>
32
+
33
+ <select id="select_by_name2">
34
+ select id, name, age from person where name = :name
35
+ </select>
36
+
37
+ <select id="select_include" include="select_all">
38
+ {{ select_all }}
39
+ {% if name -%}
40
+ where name = :name
41
+ {%- endif -%}
42
+ </select>
43
+ </mapper>
44
+
45
+ Usage Sample
46
+ ''''''''''''
47
+
48
+ .. code:: python
49
+
50
+ from typing import List, Tuple, Mapping
51
+ from batisx import mapper, sql, dbx, init_db
52
+
53
+ @mapper(namespace='person')
54
+ def select_all(): List
55
+
56
+ @mapper(namespace='person')
57
+ def select_by_name(name: str): List
58
+
59
+ @mapper(namespace='person')
60
+ def select_by_name2(name: str): List
61
+
62
+ @mapper(namespace='person')
63
+ def select_include(name: str): List
64
+
65
+ @sql('select id, name, age from person where name = ?')
66
+ def query_by_name(name: str): List(Mapping)
67
+
68
+ @sql('select id, name, age from person where name = :name')
69
+ def query_by_name2(name: str): List(Mapping)
70
+
71
+ if __name__ == '__main__':
72
+ # init_db('test.db', driver='sqlite3', show_sql=True, debug=True, mapper_path='./mapper')
73
+ # init_db("postgres://user:password@127.0.0.1:5432/testdb", driver='psycopg2', pool_size=5, mapper_path='./mapper')
74
+ init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
75
+
76
+ persons = select_all()
77
+ # result:
78
+ # (3, 'zhangsan', 15)
79
+ # (4, 'lisi', 26)
80
+ # (5, 'wangwu', 38)
81
+
82
+ persons = select_by_name('zhangsan')
83
+ # result:
84
+ # (3, 'zhangsan', 15)
85
+
86
+ persons = select_by_name2(name='zhangsan')
87
+ # result:
88
+ # (3, 'zhangsan', 15)
89
+
90
+ persons = select_include(name='zhangsan')
91
+ # result:
92
+ # (3, 'zhangsan', 15)
93
+
94
+ persons = query_by_name('zhangsan')
95
+ # result:
96
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
97
+
98
+ persons = query_by_name2(name='zhangsan')
99
+ # result:
100
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
101
+
102
+ # you can use dbx execute mapper sql with full sql id: namespace join sql id
103
+ persons = dbx.select('person.select_all') # 'person' is namespace, 'select_all' is sql id
104
+ # result:
105
+ # (3, 'zhangsan', 15)
106
+ # (4, 'lisi', 26)
107
+ # (5, 'wangwu', 38)
108
+
109
+ persons = dbx.select('person.select_by_name', name='zhangsan')
110
+ # result:
111
+ # (3, 'zhangsan', 15)
112
+
113
+ persons = dbx.sql('person.select_by_name').select(name='zhangsan')
114
+ # result:
115
+ # (3, 'zhangsan', 15)
116
+
117
+ # you can direct execute sql with db
118
+ effected_rowcount = db.insert(table='person', name='zhaoliu', age=66)
119
+
120
+ persons = db.select('select id, name, age from person')
121
+ # result:
122
+ # (3, 'zhangsan', 15)
123
+ # (4, 'lisi', 26)
124
+ # (5, 'wangwu', 38)
125
+ # (6, 'zhaoliu', 45)
126
+
127
+ persons = db.query('select id, name, age from person name = :name', name='zhangsan')
128
+ # result:
129
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
130
+
131
+ persons = db.sql('select id, name, age from person name = :name').query(name='zhangsan')
132
+ # result:
133
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
134
+
135
+ persons = db.select('select id, name, age from person where name = ?', 'zhangsan')
136
+ # result:
137
+ # [(3, 'zhangsan', 15)]
138
+
139
+
140
+ Transaction
141
+ '''''''''''
142
+
143
+ .. code:: python
144
+
145
+ from batisx import with_transaction, transaction
146
+
147
+ @with_transaction
148
+ def test_transaction():
149
+ insert_func(....)
150
+ update_func(....)
151
+
152
+
153
+ def test_transaction2():
154
+ with transaction():
155
+ insert_func(....)
156
+ update_func(....)
157
+
158
+
159
+ If you want to operate MySQL database, may be you need MySqlx: https://pypi.org/project/mysqlx
160
+
161
+ If you want to operate PostgreSQL database, may be you need MySqlx: https://pypi.org/project/pgsqlx
162
+
163
+ If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlexecx
164
+
165
+
@@ -0,0 +1 @@
1
+ mysqlx>=2.2.2
@@ -1,4 +1,4 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,36 +1,36 @@
1
- import os
2
- from setuptools import setup
3
-
4
- # INSTALL_PACKAGES = open(path.join(DIR, 'requirements.txt')).read().splitlines()
5
- def read(rel_path: str) -> str:
6
- here = os.path.abspath(os.path.dirname(__file__))
7
- # intentionally *not* adding an encoding option to open, See:
8
- # https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
9
- with open(os.path.join(here, rel_path), 'r', encoding='UTF-8') as fp:
10
- return fp.read()
11
-
12
- long_description = read("README.rst")
13
-
14
- setup(
15
- name='batisx',
16
- packages=['batisx'],
17
- description="A thread safe sql executor for Python like MyBatis with connection pool. It helps you automatically manage database connections and transactions. It also provides ORM operations for single tables.",
18
- long_description=long_description,
19
- long_description_content_type='text/markdown',
20
- install_requires=[
21
- 'mysqlx>=2.2.0',
22
- ],
23
- version='2.2.1',
24
- url='https://gitee.com/summry/batisx',
25
- author='summy',
26
- author_email='xiazhongbiao@126.com',
27
- keywords=['sql', 'MySQL', 'PostgreSQL', 'MyBatis', 'python'],
28
- package_data={
29
- # include json and txt files
30
- '': ['*.rst', '*.dtd', '*.tpl'],
31
- },
32
- include_package_data=True,
33
- python_requires='>=3.5',
34
- zip_safe=False
35
- )
36
-
1
+ import os
2
+ from setuptools import setup
3
+
4
+ # INSTALL_PACKAGES = open(path.join(DIR, 'requirements.txt')).read().splitlines()
5
+ def read(rel_path: str) -> str:
6
+ here = os.path.abspath(os.path.dirname(__file__))
7
+ # intentionally *not* adding an encoding option to open, See:
8
+ # https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
9
+ with open(os.path.join(here, rel_path), 'r', encoding='UTF-8') as fp:
10
+ return fp.read()
11
+
12
+ long_description = read("README.rst")
13
+
14
+ setup(
15
+ name='batisx',
16
+ packages=['batisx'],
17
+ description="A thread safe sql executor for Python like MyBatis with connection pool. It helps you automatically manage database connections and transactions. It also provides ORM operations for single tables.",
18
+ long_description=long_description,
19
+ long_description_content_type='text/markdown',
20
+ install_requires=[
21
+ 'mysqlx>=2.2.2',
22
+ ],
23
+ version='2.2.2',
24
+ url='https://gitee.com/summry/batisx',
25
+ author='summy',
26
+ author_email='xiazhongbiao@126.com',
27
+ keywords=['sql', 'MySQL', 'PostgreSQL', 'MyBatis', 'python'],
28
+ package_data={
29
+ # include json and txt files
30
+ '': ['*.rst', '*.dtd', '*.tpl'],
31
+ },
32
+ include_package_data=True,
33
+ python_requires='>=3.5',
34
+ zip_safe=False
35
+ )
36
+
@@ -1 +0,0 @@
1
- mysqlx>=2.2.0