Я понимаю, что модель Django довольно суетливая, когда дело касается отсутствия первичного ключа.
У меня есть устаревшая база данных (SQL Server), к которой я тоже подключаюсь (она не используется по умолчанию)и в этом у меня есть database.view, к которому я должен получить доступ. Однако проблема в том, что у представления нет первичного ключа.
Как мне включить django для запроса из этой таблицы, не имея возможности изменять схему?
Вот что я сделал:
Я создал модель ReadOnlyModel и получил свой другойДжанго модель, чтобы подкласс его. Это было сделано, потому что я хотел обойти потребность django в PK (очевидно, он работал, но вызвала другую ошибку - см. Ниже)
class ReadOnlyModel(models.Model):
def save(self, *args, **kwargs):
pass
def delete(self, *args, **kwargs):
pass
Я создал ActiveObjectManager для Django, чтобы знать, на какую базу данных указывать. Причина, по которой я использовал это на маршрутизаторе, заключается в том, что маршрутизатор работал бы лучше всего, если бы я создавал два отдельных приложения в одном репо. Тем не менее, я использую одно приложение:
class Db2ActiveObjectManager(models.Manager):
def get_queryset(self):
qs = super(Db2ActiveObjectManager, self).get_queryset()
if hasattr(self.model, 'use_db'):
qs = qs.using(self.model.use_db)
return qs
Ниже приведен пример модели из Db2:
class modelA(ReadOnlyModel):
use_db = 'db2'
objects = Db2ActiveObjectManager()
col1 = models.CharField(primary_key=True, max_length=256)
col2 = models.CharField(primary_key=True, max_length=1024)
col3 = models.CharField(primary_key=True, max_length=256)
col4 = models.CharField(primary_key=True, max_length=100)
col5 = models.CharField(max_length=256)
col6 = models.CharField(primary_key=True, max_length=50)
class Meta:
managed = False
db_table = 'db2.someTable'
@classmethod
def methodA(cls):
try:
filter_condition = {}
return cls.objects.filter(**filter_condition)
except Exception as e:
raise ValueError("Invalid input")
@classmethod
def methodB(cls):
try:
return cls.objects.raw('SQL Query Here')
# cursor = connection.cursor()
# cursor.execute('SQL Query Here')
# field_names = [field[0].lower() for field in cursor.description]
# nt_result = namedtuple('Result', field_names)
# return [nt_result(*row) for row in cursor.fetchall()]
except Exception as e:
raise
Пока моя текущая установка выдает следующую ошибку:
django.db.utils.ProgrammingError: ('42S02', "[42S02] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Invalid object name 'api_readonlymodel'. (208) (SQLExecDirectW)")
Я видел, как многие разработчики в стеке потока повторяли, что нам нужно добавить pk в таблицу / представление. Но я не могу вносить никаких изменений в эту точку зрения. Я почти уверен, что есть обходной путь, но независимо от того, что я пробовал до сих пор, у меня пока ничего не получается.
Либо я получаю вышеуказанную ошибку ^, либо я получаю сообщение об ошибке, чтоне найден правильный столбец с именем id, или я получаю сообщение о том, что мне нужен PK ...
Спасибо за помощь