Автоматизировать генерацию натуральных ключей - PullRequest
7 голосов
/ 21 декабря 2010

Я изучаю способ сериализации части данных в базе данных A и десериализации их в базе данных B (своего рода сохранение / восстановление между различными установками), и я взглянул на Django натуральные ключи , чтобы избежать проблем из-за дублированных идентификаторов.

Единственная проблема заключается в том, что я должен добавить собственный менеджер и новый метод для всех моих моделей. Есть ли способ заставить Django автоматически генерировать естественные ключи, просматривая поля unique=True или unique_togheter?

Ответы [ 4 ]

3 голосов
/ 21 декабря 2010

Обратите внимание, что этот ответ не имеет ничего общего с Джанго, но, надеюсь, даст вам еще одну альтернативу.

Вы не упомянули свою базу данных, однако в SQL Server есть ключевое слово BINARY_CHECKSUM () , которое можно использовать, чтобы дать вам уникальное значение для данных, хранящихся в строке. Думайте об этом как о хеше против всех полей в строке. Этот метод контрольной суммы можно использовать для обновления базы данных из другой, проверяя, является ли контрольная сумма локальной строки <> контрольной суммой удаленной строки.

Этот SQL ниже обновит локальную базу данных из удаленной базы данных. Он не будет вставлять новые строки, для этого вы используете insert ... where id > @MaxLocalID

SELECT  delivery_item_id, BINARY_CHECKSUM(*) AS bc
INTO    #DI
FROM    [REMOTE.NETWORK.LOCAL].YourDatabase.dbo.delivery_item di


SELECT  delivery_item_id, BINARY_CHECKSUM(*) AS bc
INTO    #DI_local
FROM    delivery_item di

-- Get rid of items that already match
DELETE  FROM #DI_local
WHERE   delivery_item_id IN (SELECT l.delivery_item_id
                             FROM   #DI x, #DI_local l
                             WHERE  l.delivery_item_id = x.delivery_item_id
                             AND l.bc = x.bc)

DROP TABLE #DI

UPDATE  DI
SET     engineer_id = X.engineer_id,
        ... -- Set other fields here
FROM    delivery_item DI,
        [REMOTE.NETWORK.LOCAL].YourDatabase.dbo.delivery_item x,
        #DI_local L
WHERE   x.delivery_item_id = L.delivery_item_id
        AND DI.delivery_item_id = L.delivery_item_id

DROP TABLE #DI_local

Чтобы вышеперечисленное работало, вам понадобится связанный сервер между вашей локальной базой данных и удаленной базой данных:

-- Create linked server if you don't have one already 
IF NOT EXISTS ( SELECT  srv.name
                FROM    sys.servers srv
                WHERE   srv.server_id != 0
                        AND srv.name = N'REMOTE.NETWORK.LOCAL' ) 
    BEGIN
        EXEC master.dbo.sp_addlinkedserver @server = N'REMOTE.NETWORK.LOCAL',
        @srvproduct = N'SQL Server'

        EXEC master.dbo.sp_addlinkedsrvlogin
        @rmtsrvname = N'REMOTE.NETWORK.LOCAL',
        @useself = N'False', @locallogin = NULL,
        @rmtuser = N'your user name',
        @rmtpassword = 'your password'
    END
GO
1 голос
/ 10 января 2011

мое решение не имеет ничего общего с естественными ключами, но использует picke / unpickle .Это не самый эффективный способ, но его легко и просто адаптировать к вашему коду.Я не знаю, работает ли он со сложной структурой БД, но если это не ваш случай, попробуйте!

при подключении к БД:файл и при подключении к БД запустить:

import pickle 
records_a = pickle.load(open('pickled.records_a.txt'))
for r in records_a:
    r.id = None
    r.save()

Надеюсь, это поможет

1 голос
/ 21 декабря 2010

В этом случае вы должны использовать GUID в качестве ключа.База данных может автоматически сгенерировать их для вас.Google уникальный идентификатор .У нас есть более 50 хранилищ, которые все вставляют данные удаленно и отправляют их в нашу основную базу данных с использованием репликации SQL Server.Все они используют GUID в качестве первичного ключа, поскольку он гарантированно будет уникальным.Работает очень хорошо.

0 голосов
/ 07 января 2011

создайте пользовательскую базовую модель, расширив класс models.Model, напишите в нем свой универсальный менеджер и метод acustom .save (), затем отредактируйте свои модели, чтобы расширить базовую модель обычного типа.это не будет иметь побочного эффекта ни на структуру таблиц БД, ни на старые сохраненные данные, за исключением случаев обновления некоторых старых строк.и если у вас были старые данные, попробуйте сделать поддельные обновления для всех ваших записей.

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