1
0
Fork 0
mirror of https://github.com/yweber/lodel2.git synced 2026-01-30 00:20:12 +01:00
lodel2_mirror/Database/sqlutils.py
2015-07-10 09:02:59 +02:00

103 lines
3.4 KiB
Python

# -*- coding: utf-8 -*-
import os
import logging as logger
import sqlalchemy as sqla
from django.conf import settings
import EditorialModel
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Lodel.settings")
ENGINES = {
'mysql': {
'driver': 'pymysql',
'encoding': 'utf8'
},
'postgresql': {
'driver': 'psycopg2',
'encoding': 'utf8',
},
'sqlite': {
'driver': 'pysqlite',
'encoding': 'utf8',
},
}
sql_config = settings.LODEL2SQLWRAPPER
## Returns an engine given dbconf name
#
# @param ename str: name of an item in django.conf.settings.LODEL2SQLWRAPPER['db']
# @param sqlaloggin None|bool: If None leave default value, if true activate sqlalchemy logging
# @return SqlAlchemy engine
def get_engine(ename='default', sqlalogging=None):
# Loading confs
cfg = sql_config['db'][ename]
edata = ENGINES[cfg['ENGINE']] # engine infos
conn_str = ""
if cfg['ENGINE'] == 'sqlite':
#SQLite connection string
conn_str = '%s+%s:///%s' % (cfg['ENGINE'], edata['driver'], cfg['NAME'])
else:
#MySQL and PostgreSQL connection string
user = cfg['USER']
user += (':' + cfg['PASSWORD'] if 'PASSWORD' in cfg else '')
if 'HOST' not in cfg:
logger.info('Not HOST in configuration, using localhost')
host = 'localhost'
else:
host = cfg['HOST']
host += (':' + cfg['PORT'] if 'PORT' in cfg else '')
conn_str = '%s+%s://' % (cfg['ENGINE'], edata['driver'])
conn_str += '%s@%s/%s' % (user, host, cfg['NAME'])
ret = sqla.create_engine(conn_str, encoding=edata['encoding'], echo=sqlalogging)
logger.debug("Getting engine :" + str(ret))
return ret
## Return a sqlalchemy.MetaData object
# @param engine sqlalchemy.engine : A sqlalchemy engine
# @return an sql alechemy MetaData instance bind to engine
def meta(engine):
res = sqla.MetaData(bind=engine)
res.reflect(bind=engine)
return res
## Return an sqlalchemy table given an EmComponent child class
# @warning Except a class type not an instance
# @param cls : An EmComponent child class
# @return An sqlalchemy table
# @throw TypeError if em_instance is an EmComponent or not an EmComponent child class (or an instance)
# @todo Move this function as an instance method ?
def get_table(self):
if not issubclass(self.__class__, EditorialModel.components.EmComponent) or self.table is None:
raise TypeError("Excepting an EmComponent child class not an " + str(self.__class__))
engine = self.db_engine
return sqla.Table(self.table, meta(engine))
## This function is intended to execute ddl defined in sqlalter
# @warning There is a dirty workaround here, DDL should returns only one query, but DropColumn for sqlite has to return 4 queries (rename, create, insert, drop). There is a split on the compiled SQL to extract and execute one query at a time
# @param ddl DDLElement: Can be an Database.sqlalter.DropColumn Database.sqlalter.AddColumn or Database.sqlalter.AlterColumn
# @param db_engine: A database engine
# @return True if success, else False
def ddl_execute(ddl, db_engine):
conn = db_engine.connect()
req = str(ddl.compile(dialect=db_engine.dialect))
queries = req.split(';')
for query in queries:
logger.debug("Executing custom raw SQL query : '" + query + "'")
ret = conn.execute(query)
if not bool(ret):
return False
conn.close()
return True