Интеграция модели Django с устаревшей базой данных - PullRequest
0 голосов
/ 11 октября 2019

Я понимаю, что модель 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 ...

Спасибо за помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...