我在使用 Laravel(使用版本 11.1.0)向 SQLite3 表中插入条目时遇到问题,特别是违反了外键约束。
我有一个使用版本 11.1.0 的 Laravel 项目,它是通过以下迁移进行设置的:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAllTables extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Create users table
Schema::create('users', function (Blueprint $table) {
$table->string('user_id')->primary();
$table->string('username')->notNullable();
// Add other user-related fields as needed
$table->timestamps();
});
// Create routes table
Schema::create('routes', function (Blueprint $table) {
$table->increments('route_id');
$table->text('polyline_data')->nullable();
$table->timestamps();
});
// Create shopping_lists table
Schema::create('shopping_lists', function (Blueprint $table) {
$table->increments('list_id');
$table->integer('user_id')->notNullable();
$table->string('name')->notNullable();
$table->integer('route_id')->unsigned()->nullable();
// Foreign keys
$table->foreign('user_id')->references('user_id')->on('users');
$table->foreign('route_id')->references('route_id')->on('routes');
$table->timestamps();
});
// Create grocery_items table
Schema::create('grocery_items', function (Blueprint $table) {
$table->increments('item_id');
$table->string('name')->notNullable();
$table->integer('quantity')->nullable();
$table->boolean('is_food')->default(false);
$table->integer('shopping_list_id')->unsigned();
$table->foreign('shopping_list_id')->references('list_id')->on('shopping_lists');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('grocery_items');
Schema::dropIfExists('shopping_lists');
Schema::dropIfExists('routes');
Schema::dropIfExists('users');
}
}
我已经运行了此迁移,目前正在尝试通过使用此控制器创建列表项来插入到 shopping_lists 表(此表包含购物清单的标题)中:
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\ShoppingList;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use App\Models\Route; // Import the Route model
use Illuminate\Support\Facades\Schema; // Necessary for debugging the schema
class ShoppingListController extends Controller
{
public function index()
{
return response()->json(ShoppingList::all(), 200);
}
public function store(Request $request)
{
Log::info("Received shopping-lists request from IP address " . $request->ip());
$userId = $request->user_id;
Log::info("User ID retrieved from JWT: " . print_r($userId, true));
// Validate the request data
$validatedData = $request->validate([
'name' => 'required|string',
'route_id' => 'nullable|integer', // Validate route_id as nullable and a valid UUID
]);
Log::info("Validated request: " . print_r($validatedData, true));
// Check if user_id exists
/*$user = DB::table('users')->where('id', $userId)->first();
if (!$user) {
Log::error("User ID $userId does not exist.");
return response()->json(['error' => 'Invalid user_id'], 400);
}*/
// Check if route_id exists (if provided)
if (!empty($validatedData['route_id'])) {
$route = DB::table('routes')->where('id', $validatedData['route_id'])->first();
if (!$route) {
Log::error("Route ID {$validatedData['route_id']} does not exist.");
return response()->json(['error' => 'Invalid route_id'], 400);
}
}
// Generate a UUID for route_id if not provided
if (empty($validatedData['route_id'])) {
$validatedData['route_id'] = null;
}
$newEntry = [
'user_id' => $userId,
'name' => $validatedData['name'],
'route_id' => $validatedData['route_id'],
];
Log::info("Entering new entry into Shopping List database: " . print_r($newEntry, true));
try {
$shoppingList = ShoppingList::create($newEntry);
Log::info("Created shopping list: " . $shoppingList);
} catch (\Exception $e) {
Log::error("Error creating shopping list: " . $e->getMessage());
return response()->json(['error' => 'Could not create shopping list'], 500);
}
return response()->json($shoppingList, 201);
}
public function show(ShoppingList $shoppingList)
{
return response()->json($shoppingList, 200);
}
public function update(Request $request, ShoppingList $shoppingList)
{
$request->validate([
'name' => 'required|string',
'route_id' => 'nullable|exists:routes,route_id',
]);
$shoppingList->update($request->all());
return response()->json($shoppingList, 200);
}
public function destroy(ShoppingList $shoppingList)
{
$shoppingList->delete();
return response()->json(null, 204);
}
}
但它在日志记录中不断给我这个错误,这清楚地表明它正在为插入提供所有字段:
[2024-05-26 17:06:07] local.ERROR: Error creating shopping list: SQLSTATE[23000]: Integrity constraint violation: 19 FOREIGN KEY constraint failed (Connection: sqlite, SQL: insert into "shopping_lists" ("user_id", "name", "route_id", "updated_at", "created_at") values (113663583418864754012, first grocery list test, ?, 2024-05-26 17:06:07, 2024-05-26 17:06:07))
我检查过,我的用户表中已经存储了一个具有此 id 值的用户,因此唯一可能导致外键问题的其他字段应该是route_id 字段。我已经浏览过其他 stackoverflow 帖子,但找不到任何解决此特定问题的方法。任何帮助将不胜感激。
在您的 user 表上,您已将 user_id 定义为字符串,而在您的 shopping_lists 表上,您已将其定义为整数。
尝试将其定义为 shopping_lists 上的字符串,方法是创建一个更改迁移 (https://laravel.com/docs/11.x/migrations#modifying-columns) 或返回并修复该迁移你有(尽管第二个选项也会删除表中已有的数据)。
更改迁移如下所示:
Schema::table('shopping_lists', function (Blueprint $table) {
$table->string('user_id')->change();
});