133 lines
2.9 KiB
Python
133 lines
2.9 KiB
Python
# -*- coding:utf8 -*-
|
||
import duckdb
|
||
from appPublic.argsConvert import ArgsConvert, ConditionConvert
|
||
from .sor import SQLor
|
||
from .const import ROWS
|
||
from .ddl_template_duckdb import duckdb_ddl_tmpl
|
||
|
||
class DuckDBor(SQLor):
|
||
"""
|
||
sqlor 方言适配:DuckDB
|
||
"""
|
||
ddl_template = duckdb_ddl_tmpl
|
||
|
||
db2modelTypeMapping = {
|
||
'boolean': 'short',
|
||
'smallint': 'short',
|
||
'integer': 'long',
|
||
'bigint': 'long',
|
||
'double': 'float',
|
||
'float': 'float',
|
||
'real': 'float',
|
||
'varchar': 'str',
|
||
'char': 'char',
|
||
'string': 'str',
|
||
'blob': 'bin',
|
||
'date': 'date',
|
||
'timestamp': 'datetime',
|
||
}
|
||
|
||
model2dbTypemapping = {
|
||
'date': 'date',
|
||
'time': 'time',
|
||
'timestamp': 'timestamp',
|
||
'str': 'varchar',
|
||
'char': 'char',
|
||
'short': 'integer',
|
||
'long': 'bigint',
|
||
'float': 'double',
|
||
'text': 'varchar',
|
||
'bin': 'blob',
|
||
'file': 'blob',
|
||
}
|
||
|
||
@classmethod
|
||
def isMe(cls, name):
|
||
return name.lower() in ['duckdb']
|
||
|
||
def grammar(self):
|
||
# duckdb 使用标准 SQL,通常不需要特殊 select_stmt
|
||
return {}
|
||
|
||
def placeHolder(self, varname, pos=None):
|
||
if varname == '__mainsql__':
|
||
return ''
|
||
return '?'
|
||
|
||
def dataConvert(self, dataList):
|
||
if isinstance(dataList, dict):
|
||
d = list(dataList.values())
|
||
else:
|
||
d = [i['value'] for i in dataList]
|
||
return tuple(d)
|
||
|
||
def pagingSQLmodel(self):
|
||
# DuckDB 兼容标准 SQL LIMIT/OFFSET
|
||
return """SELECT * FROM (%s) AS A ORDER BY $[sort]$ LIMIT $[rows]$ OFFSET $[from_line]$"""
|
||
|
||
def tablesSQL(self):
|
||
# DuckDB 不支持 INFORMATION_SCHEMA.TABLES 完全一致的结构
|
||
sqlcmd = """
|
||
SELECT lower(name) AS name, '' AS title
|
||
FROM duckdb_tables()
|
||
WHERE database_name = current_database();
|
||
"""
|
||
return sqlcmd
|
||
|
||
def fieldsSQL(self, tablename=None):
|
||
sqlcmd = """
|
||
SELECT
|
||
lower(column_name) AS name,
|
||
lower(column_type) AS type,
|
||
NULL AS length,
|
||
NULL AS dec,
|
||
'YES' AS nullable,
|
||
'' AS title,
|
||
lower(table_name) AS table_name
|
||
FROM duckdb_columns()
|
||
WHERE database_name = current_database()
|
||
"""
|
||
if tablename is not None:
|
||
sqlcmd += f" AND lower(table_name) = '{tablename.lower()}'"
|
||
return sqlcmd
|
||
|
||
def fkSQL(self, tablename=None):
|
||
# DuckDB 暂不支持外键约束查询
|
||
sqlcmd = "SELECT NULL AS constraint_name WHERE 1=0"
|
||
return sqlcmd
|
||
|
||
def pkSQL(self, tablename=None):
|
||
sqlcmd = f"""
|
||
SELECT column_name AS name
|
||
FROM duckdb_constraints()
|
||
WHERE constraint_type = 'PRIMARY KEY'
|
||
AND table_name = '{tablename.lower()}'
|
||
"""
|
||
return sqlcmd
|
||
|
||
def indexesSQL(self, tablename=None):
|
||
sqlcmd = """
|
||
SELECT
|
||
lower(index_name) AS index_name,
|
||
'' AS is_unique,
|
||
lower(column_name) AS column_name
|
||
FROM duckdb_indexes()
|
||
WHERE database_name = current_database()
|
||
"""
|
||
if tablename is not None:
|
||
sqlcmd += f" AND lower(table_name) = '{tablename.lower()}'"
|
||
return sqlcmd
|
||
|
||
async def connect(self):
|
||
self.conn = duckdb.connect(self.dbdesc.dbfile)
|
||
self.cur = self.conn
|
||
self.dbname = None
|
||
|
||
async def close(self):
|
||
self.conn.close()
|
||
|
||
def unpassword(self):
|
||
pass
|
||
|
||
|