MySQLX 2.1.1__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.
mysqlx-2.1.1/PKG-INFO ADDED
@@ -0,0 +1,182 @@
1
+ Metadata-Version: 2.1
2
+ Name: mysqlx
3
+ Version: 2.1.1
4
+ Summary: A thread safe sql executor for MySQL 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/mysqlx
6
+ Author: summy
7
+ Author-email: xiazhongbiao@126.com
8
+ License: UNKNOWN
9
+ Keywords: sql,MySQL,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
+ 'user_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/mysqlx/blob/master/dtd/mapper.dtd">
24
+ <mapper namespace="user">
25
+ <select id="select_all">
26
+ select id, name, age from user
27
+ </select>
28
+
29
+ <select id="select_by_name">
30
+ select id, name, age from user where name = ?
31
+ </select>
32
+
33
+ <select id="select_by_name2">
34
+ select id, name, age from user 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 mysqlx.orm import Model
51
+ from typing import List, Tuple, Mapping
52
+ from mysqlx import mapper, sql, db, dbx, init_db
53
+
54
+ @mapper(namespace='user')
55
+ def select_all(): List
56
+
57
+ @mapper(namespace='user')
58
+ def select_by_name(name: str): List
59
+
60
+ @mapper(namespace='user')
61
+ def select_by_name2(name: str): List
62
+
63
+ @mapper(namespace='user')
64
+ def select_include(name: str): List
65
+
66
+ @sql('select id, name, age from user where name = ?')
67
+ def query_by_name(name: str): List(Mapping)
68
+
69
+ @sql('select id, name, age from user where name = :name')
70
+ def query_by_name2(name: str): List(Mapping)
71
+
72
+ if __name__ == '__main__':
73
+ init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
74
+
75
+ users = select_all()
76
+ # result:
77
+ # (3, 'zhangsan', 15)
78
+ # (4, 'lisi', 26)
79
+ # (5, 'wangwu', 38)
80
+
81
+ users = select_by_name('zhangsan')
82
+ # result:
83
+ # (3, 'zhangsan', 15)
84
+
85
+ users = select_by_name2(name='zhangsan')
86
+ # result:
87
+ # (3, 'zhangsan', 15)
88
+
89
+ users = select_include(name='zhangsan')
90
+ # result:
91
+ # (3, 'zhangsan', 15)
92
+
93
+ users = query_by_name('zhangsan')
94
+ # result:
95
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
96
+
97
+ users = query_by_name2(name='zhangsan')
98
+ # result:
99
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
100
+
101
+ # you can use dbx execte mapper sql with full sql id: namespace join sql id
102
+ users = dbx.select('user.select_all') # 'user' is namespace, 'select_all' is sql id
103
+ # result:
104
+ # (3, 'zhangsan', 15)
105
+ # (4, 'lisi', 26)
106
+ # (5, 'wangwu', 38)
107
+
108
+ users = dbx.select('user.select_by_name', name='zhangsan')
109
+ # result:
110
+ # (3, 'zhangsan', 15)
111
+
112
+ users = dbx.sql('user.select_by_name').select(name='zhangsan')
113
+ # result:
114
+ # (3, 'zhangsan', 15)
115
+
116
+ # you can direct execute sql with db
117
+ effected_rowcount = db.insert(table='user', name='zhaoliu', age=66)
118
+
119
+ users = db.select('select id, name, age from user')
120
+ # result:
121
+ # (3, 'zhangsan', 15)
122
+ # (4, 'lisi', 26)
123
+ # (5, 'wangwu', 38)
124
+
125
+ users = db.query('select id, name, age from user name = :name', name='zhangsan')
126
+ # result:
127
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
128
+
129
+ users = db.sql('select id, name, age from user name = :name').query(name='zhangsan')
130
+ # result:
131
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
132
+
133
+ # you can use orm to operate a single table
134
+ class User(Model):
135
+ __key__ = 'id'
136
+ __table__ = 'user'
137
+
138
+ def __init__(self, id: int = None, name: str = None, age: int = None):
139
+ self.id = id
140
+ self.name = name
141
+ self.age = age
142
+
143
+
144
+ effected_rowcount = User.insert(name='tianqi', age=77)
145
+
146
+ users = User.query(name='tianqi')
147
+ # select id, name, age from user where name = :name
148
+ # result:
149
+ # {'id': 7, 'name': 'tianqi', 'age': 77}
150
+
151
+ users = User.query(name__eq='zhangsan')
152
+ # select id, name, age from user where name = :name
153
+ # result:
154
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
155
+
156
+ Transaction
157
+ '''''''''''
158
+
159
+ .. code:: python
160
+
161
+ from mysqlx import with_transaction, transaction
162
+
163
+ @with_transaction
164
+ def test_transaction():
165
+ insert_func(....)
166
+ update_func(....)
167
+
168
+
169
+ def test_transaction2():
170
+ with transaction():
171
+ insert_func(....)
172
+ update_func(....)
173
+
174
+ You can generate model class with mysqlx-generator: https://pypi.org/project/mysqlx-generator
175
+
176
+ If you want to operate PostgreSQL database, may be you need PgSqlx: https://pypi.org/project/pgsqlx
177
+
178
+ If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlx-exec
179
+
180
+ If you wanted simultaneously support MySQL and PostgreSQL, may be you need sqlx-batis: https://pypi.org/project/sqlx-batis
181
+
182
+
@@ -0,0 +1,167 @@
1
+ Mapper file
2
+ '''''''''''
3
+
4
+ Create a mapper file in 'mapper' folder, you can named
5
+ 'user_mapper.xml', like follow:
6
+
7
+ .. code:: xml
8
+
9
+ <?xml version="1.0" encoding="UTF-8"?>
10
+ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://gitee.com/summry/mysqlx/blob/master/dtd/mapper.dtd">
11
+ <mapper namespace="user">
12
+ <select id="select_all">
13
+ select id, name, age from user
14
+ </select>
15
+
16
+ <select id="select_by_name">
17
+ select id, name, age from user where name = ?
18
+ </select>
19
+
20
+ <select id="select_by_name2">
21
+ select id, name, age from user where name = :name
22
+ </select>
23
+
24
+ <select id="select_include" include="select_all">
25
+ {{ select_all }}
26
+ {% if name -%}
27
+ where name = :name
28
+ {%- endif -%}
29
+ </select>
30
+ </mapper>
31
+
32
+ Usage Sample
33
+ ''''''''''''
34
+
35
+ .. code:: python
36
+
37
+ from mysqlx.orm import Model
38
+ from typing import List, Tuple, Mapping
39
+ from mysqlx import mapper, sql, db, dbx, init_db
40
+
41
+ @mapper(namespace='user')
42
+ def select_all(): List
43
+
44
+ @mapper(namespace='user')
45
+ def select_by_name(name: str): List
46
+
47
+ @mapper(namespace='user')
48
+ def select_by_name2(name: str): List
49
+
50
+ @mapper(namespace='user')
51
+ def select_include(name: str): List
52
+
53
+ @sql('select id, name, age from user where name = ?')
54
+ def query_by_name(name: str): List(Mapping)
55
+
56
+ @sql('select id, name, age from user where name = :name')
57
+ def query_by_name2(name: str): List(Mapping)
58
+
59
+ if __name__ == '__main__':
60
+ init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
61
+
62
+ users = select_all()
63
+ # result:
64
+ # (3, 'zhangsan', 15)
65
+ # (4, 'lisi', 26)
66
+ # (5, 'wangwu', 38)
67
+
68
+ users = select_by_name('zhangsan')
69
+ # result:
70
+ # (3, 'zhangsan', 15)
71
+
72
+ users = select_by_name2(name='zhangsan')
73
+ # result:
74
+ # (3, 'zhangsan', 15)
75
+
76
+ users = select_include(name='zhangsan')
77
+ # result:
78
+ # (3, 'zhangsan', 15)
79
+
80
+ users = query_by_name('zhangsan')
81
+ # result:
82
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
83
+
84
+ users = query_by_name2(name='zhangsan')
85
+ # result:
86
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
87
+
88
+ # you can use dbx execte mapper sql with full sql id: namespace join sql id
89
+ users = dbx.select('user.select_all') # 'user' is namespace, 'select_all' is sql id
90
+ # result:
91
+ # (3, 'zhangsan', 15)
92
+ # (4, 'lisi', 26)
93
+ # (5, 'wangwu', 38)
94
+
95
+ users = dbx.select('user.select_by_name', name='zhangsan')
96
+ # result:
97
+ # (3, 'zhangsan', 15)
98
+
99
+ users = dbx.sql('user.select_by_name').select(name='zhangsan')
100
+ # result:
101
+ # (3, 'zhangsan', 15)
102
+
103
+ # you can direct execute sql with db
104
+ effected_rowcount = db.insert(table='user', name='zhaoliu', age=66)
105
+
106
+ users = db.select('select id, name, age from user')
107
+ # result:
108
+ # (3, 'zhangsan', 15)
109
+ # (4, 'lisi', 26)
110
+ # (5, 'wangwu', 38)
111
+
112
+ users = db.query('select id, name, age from user name = :name', name='zhangsan')
113
+ # result:
114
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
115
+
116
+ users = db.sql('select id, name, age from user name = :name').query(name='zhangsan')
117
+ # result:
118
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
119
+
120
+ # you can use orm to operate a single table
121
+ class User(Model):
122
+ __key__ = 'id'
123
+ __table__ = 'user'
124
+
125
+ def __init__(self, id: int = None, name: str = None, age: int = None):
126
+ self.id = id
127
+ self.name = name
128
+ self.age = age
129
+
130
+
131
+ effected_rowcount = User.insert(name='tianqi', age=77)
132
+
133
+ users = User.query(name='tianqi')
134
+ # select id, name, age from user where name = :name
135
+ # result:
136
+ # {'id': 7, 'name': 'tianqi', 'age': 77}
137
+
138
+ users = User.query(name__eq='zhangsan')
139
+ # select id, name, age from user where name = :name
140
+ # result:
141
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
142
+
143
+ Transaction
144
+ '''''''''''
145
+
146
+ .. code:: python
147
+
148
+ from mysqlx import with_transaction, transaction
149
+
150
+ @with_transaction
151
+ def test_transaction():
152
+ insert_func(....)
153
+ update_func(....)
154
+
155
+
156
+ def test_transaction2():
157
+ with transaction():
158
+ insert_func(....)
159
+ update_func(....)
160
+
161
+ You can generate model class with mysqlx-generator: https://pypi.org/project/mysqlx-generator
162
+
163
+ If you want to operate PostgreSQL database, may be you need PgSqlx: https://pypi.org/project/pgsqlx
164
+
165
+ If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlx-exec
166
+
167
+ If you wanted simultaneously support MySQL and PostgreSQL, may be you need sqlx-batis: https://pypi.org/project/sqlx-batis
@@ -0,0 +1,41 @@
1
+ from sqlbatis import (
2
+ connection,
3
+ transaction,
4
+ with_connection,
5
+ with_transaction,
6
+ get_connection,
7
+ close,
8
+ Driver,
9
+ sql,
10
+ mapper,
11
+ init_snowflake,
12
+ get_snowflake_id,
13
+ init_db as _init_db
14
+ )
15
+ from sqlexec import Dialect, Engine
16
+
17
+
18
+ def init_db(*args, **kwargs):
19
+ """
20
+ Compliant with the Python DB API 2.0 (PEP-249).
21
+
22
+ from mysqlx import init_db
23
+ init_db('test.db', driver='sqlite3', show_sql=True, debug=True)
24
+ or
25
+ init_db("postgres://user:password@127.0.0.1:5432/testdb", mapper_path='./mapper', driver='psycopg2', pool_size=5, show_sql=True, debug=True)
26
+ or
27
+ init_db(user='root', password='xxx', host='127.0.0.1', port=3306, database='testdb', mapper_path='./mapper', driver='pymysql', pool_size=5, show_sql=True, debug=True)
28
+
29
+ Addition parameters:
30
+ :param mapper_path: str, path of mapper files
31
+ :param driver=None: str, import driver, 'import pymysql'
32
+ :param pool_size=0: int, default 0, size of connection pool
33
+ :param show_sql=False: bool, if True, print sql
34
+ :param debug=False: bool, if True, print debug context
35
+ :param trans_placeholder=True: bool, if True, sql placeholder '?' --> '%s'
36
+
37
+ Other parameters of connection pool refer to DBUtils: https://webwareforpython.github.io/DBUtils/main.html#pooleddb-pooled-db
38
+ """
39
+
40
+ Dialect.init(Engine.MYSQL)
41
+ _init_db(*args, **kwargs)
@@ -0,0 +1,8 @@
1
+
2
+ # Don't remove. Import for not repetitive implementation
3
+ from sqlbatis.db import insert, save, save_sql, execute, batch_insert, batch_execute, get, query, query_one, select, select_one, do_execute,\
4
+ do_save_sql, do_get, do_query, do_query_one, do_select, do_select_one, do_query_page, do_select_page, query_page, select_page, sql, page, table,\
5
+ drop, truncate
6
+
7
+
8
+
@@ -0,0 +1,2 @@
1
+ from sqlbatis.dbx import save, batch_execute, execute, get, query, query_one, select, select_one, select_page, query_page, sql, page
2
+
@@ -0,0 +1,14 @@
1
+ # Don't remove. Import for not repetitive implementation
2
+ from sqlbatis.log_support import logger
3
+
4
+
5
+ def save_log(table, **kwargs):
6
+ logger.debug("Exec func 'mysqlx.db.save' \n\t Table: '%s', kwargs: %s" % (table, kwargs))
7
+
8
+
9
+ def sql_id_log(function: str, sql_id: str, *args, **kwargs):
10
+ logger.debug("Exec func 'mysqlx.dbx.%s', sql_id: %s, args: %s, kwargs: %s" % (function, sql_id.strip(), args, kwargs))
11
+
12
+
13
+ def orm_insert_log(function, class_name, **kwargs):
14
+ logger.debug("Exec func 'mysqlx.orm.Model.%s' \n\t Class: '%s', kwargs: %s" % (function, class_name, kwargs))
@@ -0,0 +1,142 @@
1
+ from datetime import datetime
2
+ from . import get_snowflake_id
3
+ from typing import Union, Sequence
4
+ from sqlbatis.constant import LIMIT_1
5
+ from .db import insert, do_execute, save
6
+ from .log_support import orm_insert_log, logger
7
+ import warnings
8
+
9
+ # Don't remove. Import for not repetitive implementation
10
+ from sqlbatis.orm import DelFlag, KeyStrategy, Model as BaseModel
11
+
12
+
13
+ class Model(BaseModel):
14
+ """
15
+ Create a class extends Model:
16
+
17
+ class Person(Model):
18
+ __key__ = 'id'
19
+ __table__ = 'person'
20
+ __update_by__ = 'update_by'
21
+ __update_time__ = 'update_time'
22
+ __del_flag__ = 'del_flag'
23
+
24
+ def __init__(self, id: int = None, name: str = None, age: int = None, update_by: int = None, update_time: datetime = None, del_flag: int = None):
25
+ self.id = id
26
+
27
+ self.update_by = update_by
28
+ self.update_time = update_time
29
+ self.del_flag = del_flag
30
+ self.name = name
31
+ self.age = age
32
+
33
+ then you can use like follow:
34
+ init_db(person='xxx', password='xxx', database='xxx', host='xxx', ...) # or dbx.init_db(...) init db first,
35
+ person = Person(name='张三', age=55)
36
+ effect_rowcount = person.persist()
37
+ id = person.inst_save()
38
+ """
39
+
40
+ @classmethod
41
+ def save(cls, **kwargs):
42
+ """
43
+ id = Person.save(name='张三', age=20)
44
+ :return: Primary key
45
+ """
46
+ orm_insert_log('save', cls.__name__, **kwargs)
47
+ key, table = cls._get_key_and_table()
48
+ if key in kwargs:
49
+ insert(table, **kwargs)
50
+ return kwargs[key]
51
+
52
+ key_strategy = cls._get_key_strategy()
53
+ if key_strategy == KeyStrategy.SNOWFLAKE:
54
+ kwargs[key] = get_snowflake_id()
55
+ insert(table, **kwargs)
56
+ return kwargs[key]
57
+ else:
58
+ return save(table, **kwargs)
59
+
60
+ @classmethod
61
+ def update_by_id(cls, _id: Union[int, str], **kwargs):
62
+ """
63
+ rowcount = User.update_by_id(id=1, name='王五')
64
+ return: Effect rowcount
65
+ """
66
+ logger.debug("Exec func 'mysqlx.orm.Model.%s' \n\t Class: '%s', id: %d, kwargs: %s" % ('update_by_id', cls.__name__, _id, kwargs))
67
+ assert kwargs, 'Must set update kv'
68
+ key = cls._get_key()
69
+ where = '`%s` = ?' % key
70
+ cols, args = zip(*kwargs.items())
71
+ sql, update_time_arg = cls._update_sql(where, *cols)
72
+ if update_time_arg:
73
+ args = [*args, update_time_arg]
74
+ return do_execute(sql, *args, _id, LIMIT_1)
75
+
76
+ @classmethod
77
+ def delete_by_id(cls, _id: Union[int, str]):
78
+ """
79
+ Physical delete
80
+ rowcount = User.delete_by_id(id=1)
81
+ return: Effect rowcount
82
+ """
83
+ logger.debug("Exec func 'mysqlx.orm.Model.%s' \n\t Class: '%s', id: %d" % ('delete_by_id', cls.__name__, _id))
84
+ key, table = cls._get_key_and_table()
85
+ sql = 'DELETE FROM `%s` WHERE `%s` = ? LIMIT ?' % (table, key)
86
+ return do_execute(sql, _id, LIMIT_1)
87
+
88
+ @classmethod
89
+ def _update_sql(cls, where, *update_fields):
90
+ update_time_arg = None
91
+ table = cls.get_table()
92
+ update_time_field = cls._get_update_time_field()
93
+ if update_time_field is not None and update_time_field not in update_fields:
94
+ update_fields = [*update_fields, update_time_field]
95
+ update_time_arg = datetime.now()
96
+
97
+ update_fields = ','.join(['`{}` = ?'.format(col) for col in update_fields])
98
+ return 'UPDATE `{}` SET {} WHERE {} LIMIT ?'.format(table, update_fields, where), update_time_arg
99
+
100
+ @classmethod
101
+ def _logical_delete_by_id_op(cls, _id: Union[int, str], update_by: Union[int, str] = None, del_status=DelFlag.DELETED):
102
+ key, table = cls._get_key_and_table()
103
+ del_flag_field = cls._get_del_flag_field()
104
+ update_by_field = cls._get_update_by_field()
105
+
106
+ where = '`%s` = ?' % key
107
+ if update_by is not None and update_by_field is not None:
108
+ sql, update_time_arg = cls._update_sql(where, del_flag_field, update_by_field)
109
+ if update_time_arg:
110
+ return do_execute(sql, del_status.value, update_by, update_time_arg, _id, LIMIT_1)
111
+ return do_execute(sql, del_status.value, update_by, _id, LIMIT_1)
112
+ else:
113
+ sql, update_time_arg = cls._update_sql(where, del_flag_field)
114
+ if update_time_arg:
115
+ return do_execute(sql, del_status.value, update_time_arg, _id, LIMIT_1)
116
+ return do_execute(sql, del_status.value, _id, LIMIT_1)
117
+
118
+ @classmethod
119
+ def _do_logical_delete_by_ids(cls, ids: Union[Sequence[int], Sequence[str]], update_by: Union[int, str] = None, del_status=DelFlag.DELETED):
120
+ ids_size = len(ids)
121
+ key = cls._get_key()
122
+ del_flag_field = cls._get_del_flag_field()
123
+ update_by_field = cls._get_update_by_field()
124
+
125
+ where = '`%s` in (%s)' % (key, ','.join(['?' for _ in range(ids_size)]))
126
+ if update_by is not None and update_by_field is not None:
127
+ sql, update_time_arg = cls._update_sql(where, del_flag_field, update_by_field)
128
+ if update_time_arg:
129
+ return do_execute(sql, del_status.value, update_by, update_time_arg, *ids, ids_size)
130
+ return do_execute(sql, del_status.value, update_by, *ids, ids_size)
131
+ else:
132
+ sql, update_time_arg = cls._update_sql(where, del_flag_field)
133
+ if update_time_arg:
134
+ return do_execute(sql, del_status.value, update_time_arg, *ids, ids_size)
135
+ return do_execute(sql, del_status.value, *ids, ids_size)
136
+
137
+ @classmethod
138
+ def _delete_by_ids(cls, ids: Union[Sequence[int], Sequence[str]]):
139
+ ids_size = len(ids)
140
+ key, table = cls._get_key_and_table()
141
+ sql = 'DELETE FROM `{}` WHERE `{}` in ({}) LIMIT ?'.format(table, key, ','.join(['?' for _ in range(ids_size)]))
142
+ return do_execute(sql, *ids, ids_size)
@@ -0,0 +1,182 @@
1
+ Metadata-Version: 2.1
2
+ Name: mysqlx
3
+ Version: 2.1.1
4
+ Summary: A thread safe sql executor for MySQL 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/mysqlx
6
+ Author: summy
7
+ Author-email: xiazhongbiao@126.com
8
+ License: UNKNOWN
9
+ Keywords: sql,MySQL,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
+ 'user_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/mysqlx/blob/master/dtd/mapper.dtd">
24
+ <mapper namespace="user">
25
+ <select id="select_all">
26
+ select id, name, age from user
27
+ </select>
28
+
29
+ <select id="select_by_name">
30
+ select id, name, age from user where name = ?
31
+ </select>
32
+
33
+ <select id="select_by_name2">
34
+ select id, name, age from user 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 mysqlx.orm import Model
51
+ from typing import List, Tuple, Mapping
52
+ from mysqlx import mapper, sql, db, dbx, init_db
53
+
54
+ @mapper(namespace='user')
55
+ def select_all(): List
56
+
57
+ @mapper(namespace='user')
58
+ def select_by_name(name: str): List
59
+
60
+ @mapper(namespace='user')
61
+ def select_by_name2(name: str): List
62
+
63
+ @mapper(namespace='user')
64
+ def select_include(name: str): List
65
+
66
+ @sql('select id, name, age from user where name = ?')
67
+ def query_by_name(name: str): List(Mapping)
68
+
69
+ @sql('select id, name, age from user where name = :name')
70
+ def query_by_name2(name: str): List(Mapping)
71
+
72
+ if __name__ == '__main__':
73
+ init_db(host='127.0.0.1', port='3306', user='xxx', password='xxx', database='test', pool_size=5, show_sql=True, mapper_path='./mapper')
74
+
75
+ users = select_all()
76
+ # result:
77
+ # (3, 'zhangsan', 15)
78
+ # (4, 'lisi', 26)
79
+ # (5, 'wangwu', 38)
80
+
81
+ users = select_by_name('zhangsan')
82
+ # result:
83
+ # (3, 'zhangsan', 15)
84
+
85
+ users = select_by_name2(name='zhangsan')
86
+ # result:
87
+ # (3, 'zhangsan', 15)
88
+
89
+ users = select_include(name='zhangsan')
90
+ # result:
91
+ # (3, 'zhangsan', 15)
92
+
93
+ users = query_by_name('zhangsan')
94
+ # result:
95
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
96
+
97
+ users = query_by_name2(name='zhangsan')
98
+ # result:
99
+ # {'id': 3, 'name': 'zhangsan', 'age': 15}
100
+
101
+ # you can use dbx execte mapper sql with full sql id: namespace join sql id
102
+ users = dbx.select('user.select_all') # 'user' is namespace, 'select_all' is sql id
103
+ # result:
104
+ # (3, 'zhangsan', 15)
105
+ # (4, 'lisi', 26)
106
+ # (5, 'wangwu', 38)
107
+
108
+ users = dbx.select('user.select_by_name', name='zhangsan')
109
+ # result:
110
+ # (3, 'zhangsan', 15)
111
+
112
+ users = dbx.sql('user.select_by_name').select(name='zhangsan')
113
+ # result:
114
+ # (3, 'zhangsan', 15)
115
+
116
+ # you can direct execute sql with db
117
+ effected_rowcount = db.insert(table='user', name='zhaoliu', age=66)
118
+
119
+ users = db.select('select id, name, age from user')
120
+ # result:
121
+ # (3, 'zhangsan', 15)
122
+ # (4, 'lisi', 26)
123
+ # (5, 'wangwu', 38)
124
+
125
+ users = db.query('select id, name, age from user name = :name', name='zhangsan')
126
+ # result:
127
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
128
+
129
+ users = db.sql('select id, name, age from user name = :name').query(name='zhangsan')
130
+ # result:
131
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
132
+
133
+ # you can use orm to operate a single table
134
+ class User(Model):
135
+ __key__ = 'id'
136
+ __table__ = 'user'
137
+
138
+ def __init__(self, id: int = None, name: str = None, age: int = None):
139
+ self.id = id
140
+ self.name = name
141
+ self.age = age
142
+
143
+
144
+ effected_rowcount = User.insert(name='tianqi', age=77)
145
+
146
+ users = User.query(name='tianqi')
147
+ # select id, name, age from user where name = :name
148
+ # result:
149
+ # {'id': 7, 'name': 'tianqi', 'age': 77}
150
+
151
+ users = User.query(name__eq='zhangsan')
152
+ # select id, name, age from user where name = :name
153
+ # result:
154
+ # [{'id': 3, 'name': 'zhangsan', 'age': 15}]
155
+
156
+ Transaction
157
+ '''''''''''
158
+
159
+ .. code:: python
160
+
161
+ from mysqlx import with_transaction, transaction
162
+
163
+ @with_transaction
164
+ def test_transaction():
165
+ insert_func(....)
166
+ update_func(....)
167
+
168
+
169
+ def test_transaction2():
170
+ with transaction():
171
+ insert_func(....)
172
+ update_func(....)
173
+
174
+ You can generate model class with mysqlx-generator: https://pypi.org/project/mysqlx-generator
175
+
176
+ If you want to operate PostgreSQL database, may be you need PgSqlx: https://pypi.org/project/pgsqlx
177
+
178
+ If you just wanted a simple sql executor, may be you need sqlx-exec: https://pypi.org/project/sqlx-exec
179
+
180
+ If you wanted simultaneously support MySQL and PostgreSQL, may be you need sqlx-batis: https://pypi.org/project/sqlx-batis
181
+
182
+
@@ -0,0 +1,13 @@
1
+ README.rst
2
+ setup.py
3
+ mysqlx/__init__.py
4
+ mysqlx/db.py
5
+ mysqlx/dbx.py
6
+ mysqlx/log_support.py
7
+ mysqlx/orm.py
8
+ mysqlx.egg-info/PKG-INFO
9
+ mysqlx.egg-info/SOURCES.txt
10
+ mysqlx.egg-info/dependency_links.txt
11
+ mysqlx.egg-info/not-zip-safe
12
+ mysqlx.egg-info/requires.txt
13
+ mysqlx.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ sqlx-batis>=2.1.1
@@ -0,0 +1 @@
1
+ mysqlx
mysqlx-2.1.1/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
mysqlx-2.1.1/setup.py ADDED
@@ -0,0 +1,38 @@
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='mysqlx',
16
+ packages=['mysqlx'],
17
+ description="A thread safe sql executor for MySQL 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
+ # 'Jinja2>=2.7.0',
22
+ 'sqlx-batis>=2.1.1',
23
+ # 'mysql-connector-python>=8.0.13',
24
+ ],
25
+ version='2.1.1',
26
+ url='https://gitee.com/summry/mysqlx',
27
+ author='summy',
28
+ author_email='xiazhongbiao@126.com',
29
+ keywords=['sql', 'MySQL', 'MyBatis', 'python'],
30
+ package_data={
31
+ # include json and txt files
32
+ '': ['*.rst', '*.dtd', '*.tpl'],
33
+ },
34
+ include_package_data=True,
35
+ python_requires='>=3.5',
36
+ zip_safe=False
37
+ )
38
+