#python #postgresql #sqlalchemy
#python #postgresql #sqlalchemy
Вопрос:
Почему возникает ошибка ниже? Я знаю о db.session.add()
методе, однако я хочу использовать необработанный SQL для обучения. Разве UUID не должен генерироваться автоматически? Может быть, я что-то упускаю в тексте postgresql или у меня неверный идентификатор в модели?
ошибка
Error: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, testuser, email@test.com, pASsWorD, null, 2021-01-10 16:13:23.270353-08).
models.py
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import DateTime
from sqlalchemy.sql import func
from .. import db
class Users(db.Model):
__tablename__ = 'users'
id = db.Column(
UUID(as_uuid=True),
primary_key=True,
unique=True,
)
username = db.Column(
db.String(120),
unique=True,
nullable=False
)
email = db.Column(
db.String(120),
unique=True,
nullable=False
)
password = db.Column(
db.String(120),
nullable=False
)
updated_at = db.Column(
DateTime(timezone=True),
onupdate=func.now()
)
created_at = db.Column(
DateTime(timezone=True),
server_default=func.now()
)
api.py
from flask import Blueprint, request, jsonify
from sqlalchemy import text, exc
from types import SimpleNamespace
from ...models.users import db, Users
bp = Blueprint('api', __name__, url_prefix='/api/v1')
@bp.route('/users', methods=['POST'])
def users():
if request.method == 'POST':
try:
response = dict(request.get_json())
values = SimpleNamespace(**response)
if all(response.values()):
sql_insert_one = text(f"INSERT INTO users(username, email, password) VALUES ('{values.username}', '{values.email}', '{values.password}');")
db.session.execute(sql_insert_one)
db.session.commit()
message = f"successfully added new user: {values.username}"
else:
message = f"error adding new user, values submitted: {values}"
return jsonify(response)
except Exception as err:
print(f'Error: {err}')
return jsonify(f'"error":"{err}"')
Ответ №1:
Чтобы ответить на ваш вопрос «не должен ли UUID автоматически генерироваться?» Нет. Из документов postgresql: «основная база данных не включает в себя какую-либо функцию для генерации идентификаторов UUID» ссылка.
Вам нужно сгенерировать UUID самостоятельно, попробуйте uuid.
Или вы можете использовать db.Integer
вместо db.UUID
и SQLAlchemy сделает это последовательностью, и она автоматически сгенерирует id
значение.
Комментарии:
1.
sql_insert_one = text(f"INSERT INTO users(id, username, email, password) VALUES ('{uuid.uuid4().hex}', '{values.username}', '{values.email}', '{values.password}');")
сработало, спасибо за вашу помощь.
Ответ №2:
В моем случае все в порядке с уровня кода. Но когда я перепроверяю запрос DDL таблицы (структура), автоинкремент недоступен на уровне таблицы.
CREATE TABLE public.example_table (
id int4 NOT NULL,
table_name varchar(100) NULL,
created_at timestamptz(6) NOT NULL,
created_by_id int4 NULL,
CONSTRAINT "example_table_pkey" PRIMARY KEY (id)
);
Оно должно быть
CREATE TABLE public.example_table (
id serial NOT NULL,
table_name varchar(100) NULL,
created_at timestamptz(6) NOT NULL,
created_by_id int4 NULL,
CONSTRAINT "example_table_pkey" PRIMARY KEY (id)
);
Убедитесь, что ваша структура таблицы. Это может быть полезно для кого-то