MercurySQL.gensql
Operate SQL in a more pythonic way.
This module contains the implementation of python to SQL. It provides a high-level API for operating SQL databases, which allows you to create tables, insert rows, execute queries, etc. in a more pythonic way.
For each sql engine (e.g. sqlite, mysql, …), a Driver is needed. For more details about the Driver, please refer to the MercurySQL.drivers (Drivers) section.
Warning
This module provides built-in support for anti-SQL-injection. That is, all the query values are replaced with safe queries (’?’ or else).
However, the inspection of the table name & column name is implemented by Driver s. So becareful especially when using third-party drivers.
It is recommended to hard-code the DB name, table name & column name in your code, instead of using user inputs directly.
Advanced APIs
- class MercurySQL.gensql.DataBase(db_name: str, driver=None, **kwargs)
Select/Create/Connect a SQL database.
The instance of this class represents a SQL database, and provides methods for creating tables, executing SQL, and retrieving table objects.
- __delitem__(key: str) None
Delete a table from the database, same as deleteTable().
- Parameters:
key (str) – The name of the table.
Example Usage:
db = DataBase('test.db') del db['test'] # same as db.deleteTable('test')
- __getitem__(key: str) Table
Create / Choose a table from the database.
- Parameters:
key (str) – The name of the table.
- Returns:
A Table object.
- Return type:
Example Usage:
db = DataBase('test.db') table = db['test']
- How It Works:
if exists, return the existing table (the OLD Table Object)
if not exists, create a new table by createTable().
Note
The only difference between __getitem__() and createTable() is that __getitem__() will return the OLD Table Object if exists, while createTable() will return a NEW Table Object.
See the “How It Works” section in `createTable()` for more details.
- __init__(db_name: str, driver=None, **kwargs)
Create a new database object.
- Parameters:
db_name (str) – The name of the database.
Example Usage:
db = DataBase('test.db')
- How It Works:
start a connection to the SQL database, using the driver specified by driver parameter or set_driver() method.
create a new CommandQueue to handle all SQL commands in this DB.
gather all infomations of the database, for further usages.
- createTable(*table_names: str, force: bool = False, template=None) Table
create a table in the database.
- Parameters:
table_names (str) – The name of the table.
force (bool) – Allow to return an existing table.
- Returns:
A Table object.
- Return type:
Example Usage:
db = DataBase('test.db') table = db.createTable('test')
- How It Works:
create table(s) if not exists
if already exists, return the existing table(s) in a NEW Table Object.
if exists and force set to False, raise an Exception.
- deleteTable(*table_names: str) None
delete a table in the database.
- Parameters:
table_names (str) – The name of the table.
Example Usage:
db = DataBase('test.db') db.deleteTable('test')
- How It Works:
delete table(s) if exists
raise an Exception if not exists.
- do(*sql: str, paras: List[tuple] = [])
Execute a sql command on the database.
- Parameters:
sql (str) – The sql command(s).
paras (List[tuple]) – The parameters for the sql command(s).
- Returns:
The cursor of the database.
- Return type:
Driver.Cursor
Example Usage:
db = DataBase('test.db') db.do("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)") db.do("INSERT INTO test (name) VALUES (?)", paras=[('Bernie',)]) db.do( "SQL1", "SQL2", paras=[ (paras1, paras2), (paras3, paras4) ])
- How It Works:
execute sql commands one by one, with parameters
commit after all commands are executed
- setTemplate(template: dict, **kwargs) None
Set the template, so new table’s structure will be setted to this template. You can specifd the template by using template=… parameter into db.createTable() method. Or set it after the table is created, using table.struct().
- Parameters:
template (dict) – The template to set.
**kwargs – The parameters for the template. E.g., primaryKey=’id’.
Example Usage:
db = DataBase('test.db') db.setTemplate({ 'id': int, 'name': str }) table = db.createTable('test')
- class MercurySQL.gensql.Table(db, table_name: str)
Represents a table in a SQL database. Can be created by db.createTable().
It provides methods for adding columns, deleting columns, inserting rows, and executing queries, etc.
- __delitem__(key: str) None
Delete an existing column in this table. An Exception will be raised if column not exist. Same as delColumn().
- Parameters:
key (str) – The name of the column.
Example Usage:
table = db['test'] del table['name'] # same as table.delColumn('name')
- __getitem__(key: str) Exp
get a column from the table, mainly used to construct query.
- Parameters:
key (str) – The name of the column.
- Returns:
An Exp object.
Example Usage:
Construct a query expression.
table = db['test'] exp = table['id'] == 1 res = table.select(exp)
Get the definition of a column.
table = db['test'] print(table['id']) # INTEGER PRIMARY KEY
- How It Works:
return an Exp object with table and _str attributes setted.
table is used to execute the query using list(…), even if table not specified. [NOT RECOMMENDED]
_str is used to print the definition of a column using str(…).
raise an Exception if column not exists.
- __init__(db, table_name: str)
Initialize a table object.
- Parameters:
db (DataBase) – The database object.
table_name (str) – The name of the table.
Example Usage:
db = DataBase('test.db') table = db['test']
- How It Works:
gather all infomations of the table, including columns name and their types.
set isEmpty to True if the table doesn’t have any columns. This variable will effect how the newColumn() method works.
- __setitem__(key: str, value: Any) None
Create a new column in the table.
- Parameters:
key (str) – The name of the column.
value (Any. Can be single un-parsed type (e.g. int, str(5), …) OR a tuple in the form of (type, options). (e.g. (int, ‘primary key’, ‘auto increment’))) – The type of the column.
Options in value:
‘primary key’ — Set the column as the primary key of the table.
‘auto increment’ — Set the column as an auto-incremented column.
Example Usage:
table = db['test'] table['name'] = str table['id'] = int, 'primary key', 'auto increment'
- How It Works:
get options from value if it has parameters (Judge it by whether it’s a tuple, so you can use it as the L3 of example showed).
Actually create the column, using newColumn() method.
- insert(_Table__auto=False, **kwargs) None
Insert a row into the table.
- Parameters:
__auto (bool) – Whether to update the row if it already exists.
**kwargs – The data to insert.
Example Usage:
table = db['test'] table.insert(id=1, name='Bernie', age=15, __auto=True)
- newColumn(name: str, type_: Any, force=False, primaryKey=False, autoIncrement=False) None
Add a new column to the table.
- Parameters:
name (str) – The name of the column.
type (Any) – The type of the column.
force (bool) – Allow to skip when processing an existing column.
primaryKey (bool) – Whether the column is a primary key.
autoIncrement (bool) – Whether the column is auto-incremented.
Example Usage:
table = db['test'] table.newColumn('name', str) table.newColumn('id', int, primaryKey=True)
- How It Works:
Create a new table with this column, if table is empty.
Add the column to an existing table.
Set as the primary key column if primaryKey is True.
Record its name and type in self.columns and self.columnsType.
- select(exp: Exp | None = None, selection: str = '*') QueryResult
Select data from the table.
- Parameters:
exp (Exp) – The query expression.
selection (str) – The columns to select, default is ‘*’(all columns).
- Returns:
A list of data.
- Return type:
list
Example Usage:
table = db['test'] table.select(table['id'] == 1) # select all columns where id = 1
- How It Works:
Construct a QueryResult object, which will execute the query whthin it’s QueryResult.__init__() method.
return a QueryResult object with results.
- setPrimaryKey(keyname: str, keytype: str) None
Set a column as the primary key of the table.
- Parameters:
keyname (str) – The name of the column.
keytype (str) – The type of the column, been parsed by TypeParser.
Example Usage:
table = db['test'] table.setPrimaryKey('id')
- struct(columns: dict, skipError=True, primaryKey: str | None = None, autoIncrement=False, force=True) None
Set the structure of the table.
- Parameters:
columns (dict) – The structure of the table.
skipError (bool) – Allow to skip when column exist and have the same type at the same time.
primaryKey (str) – The primary key of the table.
Example Usage:
table = db['test'] table.struct({ 'id': int, 'name': str }, primaryKey='id')
- update(exp: Exp, data: dict = {}, **kwargs) None
Update the table.
Note
We Recommend to use (tb[‘id’] == 1).update(…) then this function, for cleaner code style.
Warning
The argument of Exp.update(…) doesn’t supports kwargs format (name=bernie). It only supports dict format ({“name”: “bernie”}). We recommended to use ‘dict format’ in both table.update and Exp.update.
- Parameters:
exp (Exp) – The query expression.
data (dict) – The data to update.
Example Usage:
table = db['test'] table.update(table['id'] == 1, name='Bernie', age=15) # OR (table['id'] == 1).update({"name": "Bernie", "age": 15}) # recommended
- class MercurySQL.gensql.Exp(o1, op='', o2='', **kwargs)
Subclass of BasicExp, representing a query expression, which can be used to construct complex queries.
Supported Operations: * ==: equality * !=: inequality * <: less than * <=: less than or equal to * >: greater than * >=: greater than or equal to * .in_(): in * .like(): like * &: and * |: or * not: not
Note
you should mind the priority of operations when using some of the operators, especially & and |.
- __hash__ = None
- __init__(o1, op='', o2='', **kwargs)
Acceptable addition attributes: - table: Table …………………. the table to search - _str: str ……………………. the string to show when print the object
- __iter__()
use magic method __iter__ to search.
- __str__()
Return str(self).
- static convert(value: Any) Tuple[str, tuple]
Convert value into a form that can be used in a SQL query.
- Parameters:
value (Any) – The value to convert.
- Returns:
The converted value in the form of (sql_command, paras).
- Return type:
Tuple[str, tuple]
Example Usage:
BasicExp.convert(1) # ('?', (1,)) BasicExp.convert('Bernie') # ('?', ('Bernie',)) BasicExp.convert(None) # ('', ()) BasicExp.convert(Exp('id') == 1) # ('(id = ?)', (1,)) ...
- delete(table=None) None
Execute delete.
- formula() Tuple[str, tuple]
Return the formula of the expression in the form of (sql_command, paras).
- gen_formula() None
[Helper] Generate the formula of the expression.
Note
You can also construct a formula by yourself, just set the _formula attribute to a tuple in the form of (sql_command, paras).
- query(table=None, select='*') list
Execute query.
- update(data, /, table=None) None
Execute update.
Low-level APIs
- class MercurySQL.gensql.exp.BasicExp(exp1, oper='', exp2=None)
Basic class of Exp, representing a basic query expression that can be used to construct complex queries.
- __dict__ = mappingproxy({'__module__': 'MercurySQL.gensql.exp', '__init__': <function BasicExp.__init__>, 'convert': <staticmethod object>, 'gen_formula': <function BasicExp.gen_formula>, 'formula': <function BasicExp.formula>, '__dict__': <attribute '__dict__' of 'BasicExp' objects>, '__weakref__': <attribute '__weakref__' of 'BasicExp' objects>, '__doc__': None, '__annotations__': {}})
- __init__(exp1, oper='', exp2=None)
- static convert(value: Any) Tuple[str, tuple]
Convert value into a form that can be used in a SQL query.
- Parameters:
value (Any) – The value to convert.
- Returns:
The converted value in the form of (sql_command, paras).
- Return type:
Tuple[str, tuple]
Example Usage:
BasicExp.convert(1) # ('?', (1,)) BasicExp.convert('Bernie') # ('?', ('Bernie',)) BasicExp.convert(None) # ('', ()) BasicExp.convert(Exp('id') == 1) # ('(id = ?)', (1,)) ...
- formula() Tuple[str, tuple]
Return the formula of the expression in the form of (sql_command, paras).
- gen_formula() None
[Helper] Generate the formula of the expression.
Note
You can also construct a formula by yourself, just set the _formula attribute to a tuple in the form of (sql_command, paras).