Как остановить увеличение идентификатора первичного ключа?

Сокращенный основной код для справки:

def sqlInput(groupValues, userLogin):
    sqliteConnection = None
    try:
        sqliteConnection = sqlite3.connect('NEA.db')
        cursor = sqliteConnection.cursor()
        print()
        print("Connected to SQLite server.")
        print()
        cursor.execute('''CREATE TABLE IF NOT EXISTS "Food Tracker" (
                        ID INTEGER PRIMARY KEY,
                        "Entry Number" INTEGER,
                        "Calories" INTEGER,
                        "Food Item" TEXT,
                        "Date" TEXT,
                        "Time" TEXT
                    )''')

        insertQuery  = """INSERT INTO Food Tracker(
                                    "ID", "Food Item", "Calories", "Date", Time) 
                                VALUES 
                                (?,?,?,?,?,?)"""
        inserting = list(
                zip(userLogin.primarykey, groupValues.entry, groupValues.food, map(int, groupValues.calories), groupValues.date, groupValues.time))
        cursor.executemany(insertQuery,inserting)
        sqliteConnection.commit()
        print("Successfully entered data into SQLite database.")
        print()
        menu(userLogin)
    except sqlite3.Error as error:
        print()
        print("Failed to insert data into SQLite database:", error)
        print()
    finally:
        if sqliteConnection:
            sqliteConnection.close()

Здесь я борюсь с линиями;

 insertQuery  = """INSERT INTO Food Tracker(
                                    ID, Food Item, Calories, Date, Time) 
                                VALUES 
                                (?,?,?,?,?)"""
        inserting = list(
                zip(userLogin.primarykey, groupValues.entry, groupValues.food, map(int, groupValues.calories), groupValues.date, groupValues.time))

Все прекрасно вставляется в базу данных. Никаких проблем ни с чем, кроме столбца ID. Он не будет отображаться как мой идентификатор, который хранится в userInput.primarykey (с этим тоже нет ошибок), и вместо идентификатора, например «62381», который является действительным идентификатором примера, он будет отображаться как «1» и увеличиваться с каждым запись добавлена. Как мне сделать так, чтобы мой идентификатор оставался равным 62381, например, в userInput.primarykey, а не увеличивался?

Я пробовал добавить отдельный внешний ключ, менять порядок скобок и использовать другие команды, такие как MAP и ZIP.

Ничего не работает, ИИ не даст ответа, мне очень нужно решение. Если потребуется дополнительная информация, дайте мне знать, хотя я считаю, что добавил все, что вам нужно.

Пожалуйста, помогите мне решить эту проблему, так как у меня было много вопросов о закрытии, но это действительно, и мне нужно быстрое решение.

Сообщение об ошибке: Не удалось получить номер последней записи: Ошибка ограничения UNIQUE: Food Tracker.ID Как я могу использовать первичный ключ несколько раз?

Можете ли вы поделиться некоторыми данными и показать нам полное поведение по сравнению с ожидаемым поведением? Другими словами, поделитесь groupValues и userLogin (без конфиденциальных данных, если они есть) и как таблица после этого должна выглядеть? Похоже, вы вставляете данные, используя один и тот же первичный ключ несколько раз?

fam-woodpecker 28.03.2024 01:47

Вы уверены, что это ваш настоящий код? В вашем операторе вставки SQL есть имя таблицы Food Tracker и имя столбца Food Item со встроенными пробелами, но они не заключены в кавычки в SQL. Наверняка это ошибка.

John Gordon 28.03.2024 02:04

Код исправлен, теперь он должен быть точным.

Jush Gorania 28.03.2024 02:15

Что означает «номер записи»? Я заметил, что вы его не устанавливаете.

Schwern 28.03.2024 20:05

Вы передаете 5 или 6 параметров? У вас есть 5 столбцов, вы передаете 6 параметров, иногда 5 заполнителей, а иногда 6....

JonSG 28.03.2024 20:24
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
80
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как я могу использовать первичный ключ несколько раз?

Вы не можете. Первичный ключ должен быть уникальным.

Как мне сделать так, чтобы мой идентификатор оставался равным 62381, например, в userInput.primarykey, а не увеличивался?

Не. Оставьте идентификатор как есть и не вставляйте свой собственный. Целочисленный первичный ключ является особенным в SQLite и по умолчанию обеспечивает хороший уникальный первичный ключ. Другие базы данных потребуют от вас объявления автоинкремента или идентичности.

Вместо этого добавьте еще один столбец для хранения userLogin.primarykey.

Я могу только догадываться, что userLogin.primarykey — это идентификатор пользователя, связанного с этой строкой Food Tracker. Это должен быть «Идентификатор пользователя», объявленный как внешний ключ, ссылающийся на вашу таблицу «Пользователи».

create table "Food Tracker" (
  id integer primary key,

  "User ID" integer not null references Users(id),

  -- I notice you're not using this in your insert.
  -- What is it?
  "Entry Number" integer,
  
  "Calories" integer,
  "Food Item" text not null,

  "Date" text,
  "Time" text
)

Предполагается, что у вас есть таблица «Пользователи», на которую можно ссылаться, и что у каждого userLogin.primarykey есть запись. Возможно, вам придется вставить пользователей до того, как вы вставите информацию об их трекере еды.


Примечание 1: ваша вставка имеет 5 значений, но вы передаете 6.

Примечание 2. Будьте осторожны с CREATE TABLE IF NOT EXISTS. Если вы измените определение таблицы, это ничего не даст; вы будете использовать старое определение. Вместо этого для такой небольшой тестовой базы данных удалите таблицу и создайте ее заново.

Примечание 3. Имена столбцов с пробелами в них вызывают проблемы, пробелы используются для разделения слов. В результате вам приходится все цитировать, и в этом есть свои проблемы, например, ваш insert забывает кавычки. Кроме того, большинство баз данных игнорируют регистр, поэтому thing и Thing относятся к одному и тому же, но "Thing" может относиться только к Thing, а не к thing. Рассмотрите возможность использования thisStyle или this_style.

Примечание 4. Сохраняйте дату и время в одном столбце «Отслеживается». Это занимает меньше места и значительно упрощает работу с данными. При импорте данных вам следует устранить эти проблемы, объединить дату и время перед вставкой. Также привыкните использовать соответствующий тип datetime или timestamp (свободная обработка типов в SQLite необычна).

Не могли бы вы привести пример того, какой столбец я мог бы добавить рядом, будет ли это первичный ключ или нет? Как бы это выглядело в коде, как я пытался уже ЧАСЫ. СПАСИБО!!

Jush Gorania 28.03.2024 02:22

@JushGorania Я могу только догадываться, что userLogin.primarykey — это идентификатор пользователя, связанного с этой строкой. Это должен быть «Идентификатор пользователя», объявленный как внешний ключ, ссылающийся на вашу таблицу пользователей.

Schwern 28.03.2024 02:24

Если не сложно, не могли бы вы набросать несколько линий, как это выглядит? Я действительно не хочу просить ИИ и заставить его испортить весь мой код, а я все еще новичок в этой теме, и мне действительно нужна помощь.

Jush Gorania 28.03.2024 02:26

@JushGorania Я добавил еще немного, чтобы вы начали.

Schwern 28.03.2024 20:18

Похоже, вы говорите об автоинкрементном первичном ключе. Это обычная функция базы данных, которая обычно используется в сценариях, где нет намерения устанавливать явное значение для первичного ключа.

В этой строке DDL мы видим, что вы неявно определили столбец FoodTracker.ID как имеющий автоматически увеличивающийся первичный ключ.

ID INTEGER PRIMARY KEY,

См. этот пост для объяснения такого поведения.

Из вашей попытки вставить значение, переданное в качестве первого параметра ? в этом SQL, мы видим, что вы пытаетесь явно установить определенное значение для этого поля.

INSERT INTO Food Tracker(
                                    ID, Food Item, Calories, Date, Time) 
                                VALUES 
                                (?,?,?,?,?)

Это не сработает, однако я предлагаю вам следовать советам в принятом ответе на этот пост, который предлагает определить применение ограничения UNIQUE к идентификатору в определении вашей таблицы.

Также предлагается использовать тип данных INT вместо INTEGER, что немного странно, но было отмечено @dan04 в его комментарии к этой старой записи SO.

Различие между двумя типами данных объясняется концепцией сходства типов, о которой можно прочитать в официальной документации, раздел 3. По сути, INTEGER — это «гибкий» тип данных, который обеспечивает перекрестную совместимость с другими полями. аналогичного типа (т.е. динамически типизированного). Однако тип данных автоинкрементного первичного ключа должен вести себя так, как если бы он был статически типизирован, поэтому задается тип INT, а не сходство INTEGER.

Заглянув в раздел 2, мы читаем

Любой столбец в базе данных SQLite версии 3, кроме INTEGER PRIMARY. Столбец KEY может использоваться для хранения значения любого класса хранения.

это, по-видимому, предполагает, что столбец, определенный таким образом, не сможет хранить значение, подобное тому, которое вы пытались вставить.

В ответ на ваш комментарий к этому сообщению кажется, что @Schwern был прав насчет ваших намерений вставить ссылку на внешний ключ, а не значение первичного ключа, как вы это первоначально описали.

В этом случае, хотя вышеизложенное справедливо и для первичных ключей, вам, вероятно, понадобятся операторы DDL примерно такого типа:

CREATE TABLE IF NOT EXISTS "UserLogin" (
                        ID INTEGER PRIMARY KEY,
                        "UserName" TEXT
);


CREATE TABLE IF NOT EXISTS "Food Tracker" (
                        ID INTEGER PRIMARY KEY,
                        "UserLoginId" INTEGER,
                        "Entry Number" INTEGER,
                        "Calories" INTEGER,
                        "Food Item" TEXT,
                        "Date" TEXT,
                        "Time" TEXT,
                        FOREIGN KEY (UserLoginId) REFERENCES UserLogin (ID)
);

Я демонстрирую это здесь на языке SQL, чтобы показать основную логику, но при необходимости вы можете реализовать это с помощью соответствующей параметризации в своем приложении Python.

Сначала убедитесь, что у нас есть пользователь:

INSERT INTO UserLogin (
    UserName  
)
VALUES ('42123');

Затем добавляем запись в трекер еды.

INSERT INTO "Food Tracker" (
    "UserLoginId", 
    "Entry Number"
    --,etc.
) 
SELECT
    (
        SELECT Id FROM UserLogin
        WHERE UserName = '42123'
    ) as UserLoginId,
    7 as [EntryNumber];

Обратите внимание, что первичный ключ Food Tracker не указан во вставке. Также обратите внимание на подзапрос, который позволяет нам ссылаться на конкретного пользователя с помощью свободно определяемой строки, сохраняя при этом уникальный, автоматически увеличивающийся первичный ключ в таблице UserLogin. Это часто бывает полезно и является рекомендуемым дизайном таблицы.

Наконец, мы можем запросить информацию отслеживания, относящуюся к конкретному пользователю, с помощью простого поиска:

SELECT
    ul.UserName,
    ft.* 
FROM "Food Tracker" ft
    INNER JOIN UserLogin ul ON ft.UserLoginId = ul.Id
WHERE ul.UserName = '42123';

В конечном счете, меня беспокоит не инструмент автоматического увеличения, а то, как я могу найти способ использовать первичный ключ в нескольких столбцах, даже если это то, что я хочу, например, когда вы вводите SELECT * ОТ Имя пользователя; ГДЕ Имя пользователя = «42123»; Там будет список записей Food Tracker от пользователя 42123 с течением времени.

Jush Gorania 28.03.2024 02:31

Я не думаю, что их имя пользователя — 42123. Похоже, их уникальный идентификатор подходит для первичного ключа.

Schwern 28.03.2024 20:20

Другие вопросы по теме