2015-01-13 04:20:40 +08:00
|
|
|
import datetime
|
|
|
|
|
|
|
|
from .base import Database
|
|
|
|
|
|
|
|
|
2019-06-10 19:56:50 +08:00
|
|
|
class InsertVar:
|
2015-01-13 04:20:40 +08:00
|
|
|
"""
|
|
|
|
A late-binding cursor variable that can be passed to Cursor.execute
|
|
|
|
as a parameter, in order to receive the id of the row created by an
|
|
|
|
insert statement.
|
|
|
|
"""
|
2019-06-10 19:56:50 +08:00
|
|
|
types = {
|
2019-07-24 14:39:45 +08:00
|
|
|
'AutoField': int,
|
|
|
|
'BigAutoField': int,
|
|
|
|
'SmallAutoField': int,
|
|
|
|
'IntegerField': int,
|
|
|
|
'BigIntegerField': int,
|
|
|
|
'SmallIntegerField': int,
|
2019-10-16 20:32:12 +08:00
|
|
|
'PositiveBigIntegerField': int,
|
2019-07-24 14:39:45 +08:00
|
|
|
'PositiveSmallIntegerField': int,
|
|
|
|
'PositiveIntegerField': int,
|
2019-06-10 19:56:50 +08:00
|
|
|
'FloatField': Database.NATIVE_FLOAT,
|
|
|
|
'DateTimeField': Database.TIMESTAMP,
|
2019-07-24 14:41:32 +08:00
|
|
|
'DateField': Database.Date,
|
2019-06-10 19:56:50 +08:00
|
|
|
'DecimalField': Database.NUMBER,
|
|
|
|
}
|
|
|
|
|
|
|
|
def __init__(self, field):
|
|
|
|
internal_type = getattr(field, 'target_field', field).get_internal_type()
|
2019-07-24 14:39:45 +08:00
|
|
|
self.db_type = self.types.get(internal_type, str)
|
2019-09-15 05:50:14 +08:00
|
|
|
self.bound_param = None
|
2019-06-10 19:56:50 +08:00
|
|
|
|
2015-01-13 04:20:40 +08:00
|
|
|
def bind_parameter(self, cursor):
|
2019-09-15 05:50:14 +08:00
|
|
|
self.bound_param = cursor.cursor.var(self.db_type)
|
|
|
|
return self.bound_param
|
|
|
|
|
|
|
|
def get_value(self):
|
|
|
|
return self.bound_param.getvalue()
|
2015-01-13 04:20:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
class Oracle_datetime(datetime.datetime):
|
|
|
|
"""
|
|
|
|
A datetime object, with an additional class attribute
|
|
|
|
to tell cx_Oracle to save the microseconds too.
|
|
|
|
"""
|
|
|
|
input_size = Database.TIMESTAMP
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def from_datetime(cls, dt):
|
|
|
|
return Oracle_datetime(
|
|
|
|
dt.year, dt.month, dt.day,
|
|
|
|
dt.hour, dt.minute, dt.second, dt.microsecond,
|
|
|
|
)
|
2017-02-07 12:49:31 +08:00
|
|
|
|
|
|
|
|
|
|
|
class BulkInsertMapper:
|
|
|
|
BLOB = 'TO_BLOB(%s)'
|
2019-10-01 20:46:10 +08:00
|
|
|
CLOB = 'TO_CLOB(%s)'
|
2017-02-07 12:49:31 +08:00
|
|
|
DATE = 'TO_DATE(%s)'
|
|
|
|
INTERVAL = 'CAST(%s as INTERVAL DAY(9) TO SECOND(6))'
|
|
|
|
NUMBER = 'TO_NUMBER(%s)'
|
|
|
|
TIMESTAMP = 'TO_TIMESTAMP(%s)'
|
|
|
|
|
|
|
|
types = {
|
2020-02-28 14:50:24 +08:00
|
|
|
'AutoField': NUMBER,
|
|
|
|
'BigAutoField': NUMBER,
|
2017-02-07 12:49:31 +08:00
|
|
|
'BigIntegerField': NUMBER,
|
|
|
|
'BinaryField': BLOB,
|
2017-05-06 22:56:28 +08:00
|
|
|
'BooleanField': NUMBER,
|
2017-02-07 12:49:31 +08:00
|
|
|
'DateField': DATE,
|
|
|
|
'DateTimeField': TIMESTAMP,
|
|
|
|
'DecimalField': NUMBER,
|
|
|
|
'DurationField': INTERVAL,
|
|
|
|
'FloatField': NUMBER,
|
|
|
|
'IntegerField': NUMBER,
|
2019-10-16 20:32:12 +08:00
|
|
|
'PositiveBigIntegerField': NUMBER,
|
2017-02-07 12:49:31 +08:00
|
|
|
'PositiveIntegerField': NUMBER,
|
|
|
|
'PositiveSmallIntegerField': NUMBER,
|
2020-02-28 14:50:24 +08:00
|
|
|
'SmallAutoField': NUMBER,
|
2017-02-07 12:49:31 +08:00
|
|
|
'SmallIntegerField': NUMBER,
|
2019-10-01 20:46:10 +08:00
|
|
|
'TextField': CLOB,
|
2017-02-07 12:49:31 +08:00
|
|
|
'TimeField': TIMESTAMP,
|
|
|
|
}
|
2020-10-05 06:25:29 +08:00
|
|
|
|
|
|
|
|
|
|
|
def dsn(settings_dict):
|
|
|
|
if settings_dict['PORT']:
|
|
|
|
host = settings_dict['HOST'].strip() or 'localhost'
|
|
|
|
return Database.makedsn(host, int(settings_dict['PORT']), settings_dict['NAME'])
|
|
|
|
return settings_dict['NAME']
|