SQL Server — как вставлять значения в таблицы, которые ссылаются друг на друга

#python #sql #sql-server #database

#python #sql #sql-сервер #База данных

Вопрос:

Пытаюсь вставить в базу данных MS SQL, но меня поражает эта ошибка:

Оператор INSERT конфликтует с ограничением ВНЕШНЕГО КЛЮЧА

Исходная ошибка (на немецком языке)

 pypyodbc.IntegrityError: (u'23000', u'[23000] [Microsoft][ODBC SQL Server Driver][SQL Server]Die INSERT-Anweisung steht in Konflikt mit der FOREIGN KEY-Einschrxe4nkung "FK_tCompanyLocation_tCompany". Der Konflikt trat in der Test-Datenbank, Tabelle "dbo.tCompany", column 'GUID' auf.')
  

Теперь …. Мне кажется , я получаю сообщение об ошибке … при вставке в tCompanyLocation, company_guid (GUID) не будет в таблице tCompany, так как он будет вставлен в мой скрипт как второй. Однако tCompany также нуждается в company_location_guid (LocationGUID), поэтому я не могу выполнить его раньше….

Мне кажется, это проблема с курицей и яйцом… Я не могу вставить в tCompany из-за tCompanyLocation и наоборот.

 import uuid
import pypyodbc

company_guid = uuid.uuid4()
company_guid = str(company_guid).upper()
company_location_guid = uuid.uuid4()
company_location_guid = str(company_location_guid).upper()
position_guid = uuid.uuid4()
position_guid = str(position_guid).upper()
department_guid = uuid.uuid4()
department_guid= str(department_guid).upper()
experience_guid = uuid.uuid4()
experience_guid = str(experience_guid).upper()
people_guid = uuid.uuid4()
people_guid = str(people_guid).upper()

cnxn = pypyodbc.connect('DRIVER={SQL Server};SERVER=127.0.0.1;DATABASE=Test;UID=sa;PWD=password')
cursor = cnxn.cursor()


def insert_company_location():

    sql = """
    INSERT
    INTO[dbo].[tCompanyLocation]
    ([GUID]
     , [CompanyGUID]
     , [LocationName]
     , [Address1]
     , [Address2]
     , [City]
     , [Zipcode]
     , [Phone]
     , [Fax]
     , [TimeEntered]
     , [TimeUpdated]
     , [UserEnteredGUID]
     , [UserUpdatedGUID]
     , [UpdateHistory]
     , [PhoneCountryCode]
     , [FaxCountryCode]
     , [CountryGUID]
     , [CompanyLocationNotes]
     , [RegionGUID]
     , [Region2GUID])

VALUES
( """   "'"   company_location_guid   "'"   """
, """   "'"   company_guid   "'"   """
, 'New York, NY'
, 'Street 1'
, 'Street 2'
, 'New York'
, '10165'
, ' 12121234123'
, ' 12129124123'
, '2009-01-01 14:47:05.250'
, '2009-01-01 14:47:05.250'
, NULL
, NULL
, NULL
, '1'
, NULL
, '25B825CF-BDD0-11D5-93E2-00D0B7471F8B'
, NULL
, 'D2490D0A-140D-4D52-A57E-47909B6C222B'
, NULL)
"""
    print(sql)
    cursor.execute(sql)

def insert_company():

    sql = """

    INSERT
    INTO[dbo].[tCompany]
    ([GUID]
     , [CompanyTypeGUID]
     , [BranchOfGUID]
     , [CurrencyGUID]
     , [CompanyName]
     , [PrintName]
     , [LocationGUID]
     , [Website]
     , [FeePercent]
     , [FeeAmount]
     , [FeeNotes]
     , [Bio]
     , [CompanyNotes]
     , [CompanyDoNotPrint]
     , [CompanyCode]
     , [AlertMessage]
     , [TimeEntered]
     , [UserEnteredGUID]
     , [TimeUpdated]
     , [UserUpdatedGUID]
     , [UpdateHistory]
     , [CompanyLocationNotes]
     , [ExternalDocument])


VALUES
(  """   "'"   company_guid   "'"   """
, NULL
, NULL
, '2104105B-31CA-11D4-BC2A-0050DA246141'
, 'IBM'
, NULL
, """   "'"   company_location_guid   "'"   """
, 'http://www.ibm.com'
, '0.0000'
, '0,00'
, NULL
, NULL
, NULL
, '0'
, NULL
, NULL
, '2010-01-01 11:30:52.780'
, 'C9678062-0E21-4E2A-9707-4564E00B8678'
, '2010-02-01 11:31:53.000'
, 'C9678062-0E21-4E2A-9707-4564E00B8678'
, NULL
, NULL
, '0')
"""
    cursor.execute(sql)
  

Вопрос:

Как решить эту проблему? Я знаю, что генерация GUID из Python плоха, но как я могу добиться этого, не делая этого на Python? Если кто-нибудь может показать мне, как вставить в эти 2 таблицы, это было бы здорово.

Комментарии:

1. Я сомневаюсь в дизайнерском решении иметь LocationGUID в tCompany таблице. CompanyGUID уже есть в tCompanyLocation таблице, и это правильное отношение. Дизайн, который у вас есть сейчас, приведет к соотношению 1: 1 между Company и CompanyLocation. Можно ли изменить дизайн или ограничения?

2. К сожалению, я не могу изменить структуру / дизайн базы данных. Есть идеи, как решить мою проблему? Или это неразрешимо:( ? Я новичок в MS SQL Server и проектировании БД… работал с простыми базами данных в MySQL и PostgreSQL.

3. В этом случае существует ли ограничение на LocationGUID столбец в tCompany таблице? Если нет, вы можете создать Company запись, сначала поместив временное значение в LocationGUID столбец, затем вставить tCompanyLocation запись с новым CompanyGUID значением, затем вернуться назад и обновить LocationGUID столбец tCompany с правильным значением. Если для обеих таблиц существует ограничение для идентификаторов GUID, то я бы очень, очень настаивал на том, чтобы ограничение было удалено из tCompany таблицы, поскольку таким образом будет невозможно добавлять записи,

4. БОЛЬШОЕ ВАМ СПАСИБО!!! Я думаю, я понял вашу точку зрения. Ограничение заключается в том, что в таблице tCompany есть «FK_tCompany_tCompanyLocation», где ПРИ tCompanyLocation GUID подключен к FK tcompany LocationGUID. После того, как я снял это ограничение, оно, похоже, сработало. Является ли мой пример хорошей идеей для создания GUID в Python? Как я могу убедиться, что сгенерированный GUID уже не существует? Как я могу решить проблему генерации уникального идентификатора GUID, который я могу использовать в запросах в качестве переменной Python? Есть идеи?

5. Хорошо — рад, что это работает. Генерация GUID из Python неплоха , но мне, как правило, не нравится позволять моему языку делать подобные вещи. Я обычно позволяю базе данных делать это, например, через столбцы идентификаторов или NEWID (см. MSDN ). Чтобы обеспечить уникальный идентификатор GUID, вы можете выполнить простой поиск внутри своей insert_company функции, чтобы сначала проверить наличие идентификатора GUID (а также другие вещи, такие как название компании и т. Д.). и обрабатывать, если он уже существует. Не совсем уверен, что вы имеете в виду в своем последнем вопросе — я бы предложил, возможно, новый пост об этом здесь.