Skip to main content

Tabnine

Tabnine 是一个 AI 软件开发平台,它是 IDE(例如 VS Code、WebStorm、IntelliJ 等)的 extension

¥Tabnine is a an AI software development platform that comes as an extension for your IDE (e.g. VS Code, WebStorm, IntelliJ, ...).

概述

¥Overview

它通过以下方式帮助开发者更快地编写代码:

¥It helps developers write code faster by:

  • 在编辑器中为小型重复编码任务提供上下文感知的 代码完成 建议

    ¥Providing context-aware code completion suggestions in the editor for small, repetitive coding tasks

  • 为更高级别的任务提供集成的 chat 和详细说明

    ¥Offering an integrated chat for higher-level tasks and detailed instructions

为什么将 Prisma ORM 与 Tabnine 一起使用?

¥Why use Prisma ORM with Tabnine?

像 Tabnine 这样的 AI 编辑器是功能强大的工具,可以大大提高开发者的工作效率。它特别适合以下工作流程:

¥AI editors like Tabnine are powerful tools that can drastically improve developer productivity. It works especially well with the following workflows:

  • 数据建模和数据库模式设计

    ¥Data modeling and database schema design

  • 构建和优化数据库查询

    ¥Constructing and optimizing database queries

  • 生成 CRUD 功能和其他样板代码

    ¥Generating CRUD functionality and other boilerplate code

  • 生成可与 TypedSQL 一起使用的纯 SQL 查询

    ¥Generating plain SQL queries that can be used with TypedSQL

  • 为单元和集成测试生成代码

    ¥Generating code for unit and integrations tests

  • 指导主要重构

    ¥Guiding through major refactorings

  • 生成种子脚本

    ¥Generating seeding scripts

利用 Prisma 模式

¥Leveraging the Prisma schema

由于 Prisma 有自己的 schema,因此 Tabnine 可以理解数据的基本形状并帮助你为堆栈的其他部分编写代码。

¥Because Prisma has its own schema, Tabnine can understand the basic shape of your data and help you write code for the other parts of your stack.

因此,我们建议你首先定义 Prisma 架构,然后使用 Tabnine 围绕它构建应用层(包括 API 调用、DTO、业务逻辑、第三方集成等)。

¥We therefore recommend that you start out by defining your Prisma schema and then use Tabnine to build the application layer around it (inluding API calls, DTOs, business logic, 3rd party integrations, ...).

数据建模和数据库模式设计

¥Data modeling and database schema design

Tabnine 如何提供帮助

¥How Tabnine helps

从头开始设计数据库模式涉及大量样板,并且可能非常耗时。

¥Designing a database schema from scratch involves a lot of boilerplate and can be time-consuming.

Tabnine 可以通过以下方式加速此过程:

¥Tabnine can accelerate this process by:

  • 为模型、索引、约束和关系生成样板。

    ¥Generating boilerplate for models, indexes, constraints, and relations.

  • 通过遵守命名和其他约定来保持架构一致。

    ¥Keeping the schema consistent by sticking to naming and other conventions.

  • 基于常见数据库模式自动补齐模型和字段定义。

    ¥Auto-completing model and field definitions based on common database patterns.

  • 根据命名约定建议关系和字段类型。

    ¥Suggesting relationships and field types based on naming conventions.

示例:定义 Prisma 模式

¥Example: Defining a Prisma schema

提示

¥Prompt

使用用户、组织和订阅模型为 SaaS 应用定义 Prisma 模式。确保关系设置正确。

¥Define a Prisma schema for a SaaS application with User, Organization, and Subscription models. Ensure relationships are properly set up.

生成的代码

¥Generated code

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
email String @unique
name String
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int
}

model Organization {
id Int @id @default(autoincrement())
name String
slug String @unique
subscription Subscription?
users User[]
}

model Subscription {
id Int @id @default(autoincrement())
organization Organization @relation(fields: [organizationId], references: [id])
organizationId Int @unique
plan String
status Status
}

enum Status {
Active
Paused
Expired
}

构建和优化数据库查询

¥Constructing and optimizing database queries

Tabnine 如何提供帮助

¥How Tabnine helps

Prisma ORM 提供了一个方便的高级 API,可以直观地编写数据库查询。但是,涉及过滤器、分页和高级模式的查询仍然可能变得复杂。

¥Prisma ORM provides a convenient high-level API for writing database queries intuitively. However, queries involving filters, pagination and advanced patterns can still become complex to construct.

Tabnine 可以通过以下方式提供帮助:

¥Tabnine can help by:

  • 根据架构自动补齐 Prisma 查询。

    ¥Auto-completing Prisma queries based on the schema.

  • 建议过滤器使用 where 子句,分页逻辑使用 skip / take 选项。

    ¥Suggesting where clauses for filters and skip / take options for pagination logic.

  • 帮助提高效率和性能。

    ¥Helping with efficiency and performance optimizations.

示例:获取具有关系的数据

¥Example: fetching data with relationships

提示

¥Prompt

生成 Prisma 查询以从具有活跃订阅的组织中获取所有活跃用户。在查询结果中包含有关用户组织的数据。

¥Generate a Prisma query to fetch all active users from an organization with an active subscription. Include data about the users' organizations in the query result.

生成的代码

¥Generated code

const activeUsers = await prisma.user.findMany({
where: {
organization: {
subscription: {
status: "ACTIVE"
}
}
},
include: {
organization: true
}
});

生成 CRUD 功能和其他样板代码

¥Generating CRUD functionality and other boilerplate code

Tabnine 如何提供帮助

¥How Tabnine helps

大多数应用需要基本的 CRUD 操作或其他样板代码,这些代码通常来自数据库架构的结构。例如,API 层可能会公开一组 HTTP 端点,允许创建、读取、更新或删除某个模型的记录。类似地,前端将数据提取和状态管理逻辑与这些 API 端点交互并相应地更新 UI。

¥Most applications require basic CRUD operations or other boilerplate code that's usually derived from the structure of the database schema. For example, an API layer may expose a set of HTTP endpoints that allow to create, read, update or delete records of a certain model. Similarly, a frontend will data fetching and state management logic to interact with these API endpoints and update the UI accordingly.

Tabnine 无需手动编写此代码,而是可以通过以下方式加快此过程:

¥Instead of writing this code manually, Tabnine can speed up this process by:

  • 为后端生成 Prisma createreadupdatedelete 操作,为前端生成 UI 组件。

    ¥Generating Prisma create, read, update, and delete operations for the backend and UI components for the frontend.

  • 自动补齐函数名称和参数类型。

    ¥Auto-completing function names and argument types.

  • 编写样板代码,同时遵循使用 DTO、错误处理、一致的 API 设计等最佳实践。

    ¥Write boilerplate code while following best practices for using DTOs, error handling, consistent API design, ...

示例:使用 Next.js 生成 CRUD 功能

¥Example: Generating CRUD functionality with Next.js

提示

¥Prompt

根据上述模式中的用户模型为 Next.js 应用生成 CRUD 功能。

¥Generate CRUD functionality for a Next.js app based on the User model from the schema above.

生成的代码

¥Generated code

API 端点

¥API endpoints

filename=app/api/users/routes.ts
import { NextResponse } from 'next/server';
import prisma from '../../../lib/prisma';

export async function GET() {
const users = await prisma.user.findMany({
include: { organization: true },
});
return NextResponse.json(users);
}

export async function POST(request: Request) {
const body = await request.json();
const user = await prisma.user.create({
data: {
email: body.email,
name: body.name,
organization: {
connect: { id: body.organizationId },
},
},
include: { organization: true },
});
return NextResponse.json(user);
}

export async function PUT(request: Request) {
const body = await request.json();
const user = await prisma.user.update({
where: { id: body.id },
data: {
email: body.email,
name: body.name,
organizationId: body.organizationId,
},
include: { organization: true },
});
return NextResponse.json(user);
}

export async function DELETE(request: Request) {
const { searchParams } = new URL(request.url);
const id = searchParams.get('id');
const user = await prisma.user.delete({
where: { id: Number(id) },
});
return NextResponse.json(user);
}
React 组件

¥React components

filename=app/components/User.tsx
import React, { useState, useEffect } from 'react';

interface User {
id: number;
email: string;
name: string;
organizationId: number;
}

const User: React.FC = () => {
const [users, setUsers] = useState<User[]>([]);
const [newUser, setNewUser] = useState({ email: '', name: '', organizationId: 0 });

useEffect(() => {
fetchUsers();
}, []);

const fetchUsers = async () => {
const response = await fetch('/api/users');
const data = await response.json();
setUsers(data);
};

const createUser = async () => {
await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newUser),
});
fetchUsers();
setNewUser({ email: '', name: '', organizationId: 0 });
};

const deleteUser = async (id: number) => {
await fetch(`/api/users?id=${id}`, { method: 'DELETE' });
fetchUsers();
};

return (
<div>
<h2>Users</h2>
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name} ({user.email}) - Org ID: {user.organizationId}
<button onClick={() => deleteUser(user.id)}>Delete</button>
</li>
))}
</ul>
<h3>Create New User</h3>
<input
type="text"
placeholder="Name"
value={newUser.name}
onChange={(e) => setNewUser({ ...newUser, name: e.target.value })}
/>
<input
type="email"
placeholder="Email"
value={newUser.email}
onChange={(e) => setNewUser({ ...newUser, email: e.target.value })}
/>
<input
type="number"
placeholder="Organization ID"
value={newUser.organizationId}
onChange={(e) => setNewUser({ ...newUser, organizationId: Number(e.target.value) })}
/>
<button onClick={createUser}>Create User</button>
</div>
);
};

export default User;

生成用于 TypedSQL 的纯 SQL 查询

¥Generating plain SQL queries for use with TypedSQL

Tabnine 如何提供帮助

¥How Tabnine helps

虽然 Prisma 提供了用于查询的高级 API,但有时开发者可能需要降级到原始 SQL 以对查询进行更底层的控制。在这些情况下,他们可以使用 TypedSQL,它为 Prisma ORM 中的 raq SQL 查询提供完全类型安全性。

¥While Prisma provides a high-level API for querying, sometimes a developer may need to drop down to raw SQL for more low-level control of a query. In these cases, they can use TypedSQL which provides full type safety for raq SQL queries in Prisma ORM.

一个常见的用例是聚合查询,例如计算上述模式示例中不同订阅状态的百分比。

¥One common use case are aggregation queries, such as calculating percentages of different subscription statuses in the schema example above.

Tabnine 可以通过以下方式提供帮助:

¥Tabnine can assist by:

  • 根据你的 Prisma 模式生成 SQL 查询。

    ¥Generating SQL queries based on your Prisma schema.

  • 无需手动反复试验即可构建复杂的聚合。

    ¥Structuring complex aggregations without manual trial and error.

  • 将查询集成到你的应用代码中。

    ¥Integrating the queries in your application code.

示例:计算活跃、过期和暂停订阅的百分比

¥Example: Calculating the percentages of active, expired, and paused subscriptions

提示

¥Prompt

生成 SQL 查询,返回活动、暂停和已过期订阅的百分比。

¥Generate a SQL query that returns the percentage of subscriptions that are Active, Paused, and Expired.

生成的 SQL 查询

¥Generated SQL query

prisma/sql/subscriptionsReport.sql
SELECT 
status,
COUNT(*) * 100.0 / (SELECT COUNT(*) FROM "Subscription") AS percentage
FROM "Subscription"
GROUP BY status;

应用代码

¥Application code

import { PrismaClient } from '@prisma/client'
import { subscriptionsReport } from '@prisma/client/sql'

const prisma = new PrismaClient();

const usersWithPostCounts = await prisma.$queryRawTyped(subscriptionsReport())
console.log(usersWithPostCounts)

生成单元和集成测试的代码

¥Generating code for unit and integration tests

Tabnine 如何提供帮助

¥How Tabnine helps

编写测试可确保基于 Prisma 的应用正常运行并根据要求和期望运行。但是,编写测试是一项耗时的活动,通常遵循可预测和重复的模式。

¥Writing tests ensures that Prisma-based applications function correctly and behave according to requirements and expectations. However, writing tests is a time-consuming activity that often follows predictable and repetitive patterns.

Tabnine 可以通过以下方式大幅加快编写测试的速度:

¥Tabnine can drastically speed up writing tests by:

  • 为单元测试和集成测试生成测试样板。

    ¥Generating test boilerplate for both unit and integration tests.

  • 建议 Prisma 数据库交互的模拟和装置。

    ¥Suggesting mocks and fixtures for Prisma database interactions.

  • 帮助构建测试用例以遵循最佳实践。

    ¥Helping structure test cases to follow best practices.

  • 提供集成测试脚手架,用于使用真实或内存数据库测试 Prisma。

    ¥Providing integration test scaffolding for testing Prisma with a real or in-memory database.

示例:为 Prisma 服务编写单元测试

¥Example: Writing a unit test for a Prisma service

提示

¥Prompt

为获取所有活跃用户的 Prisma 服务功能生成 Jest 单元测试。

¥Generate a Jest unit test for a Prisma service function that fetches all active users.

生成的代码

¥Generated code

filename=__tests__/userService.test.ts
import { prismaMock } from '../prisma/singleton';
import { getActiveUsers } from '../services/userService';

test('should return only active users', async () => {
prismaMock.user.findMany.mockResolvedValue([
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
]);

const users = await getActiveUsers();
expect(users).toHaveLength(2);
expect(users[0].email).toBe('alice@example.com');
});

指导主要重构

¥Guiding through major refactorings

Tabnine 如何提供帮助

¥How Tabnine helps

得益于 Prisma ORM 的类型安全查询,重构比使用其他 ORM 更安全、更可预测:进行架构更改后,生成的 Prisma Client 代码将被更新,TypeScript 编译器将高亮所有需要更改的地方。

¥Thanks to Prisma ORM's type safe queries, refactoring are more safe and predictable than with other ORMs: After making schema changes, the generated Prisma Client code will be updated and the TypeScript compiler will highlight all places that need a change.

但是,重构过程中可能仍会出现更困难的情况,例如需要调整业务逻辑或复杂查询时。

¥However, there may still be more difficult situations during a refactoring, e.g. when business logic or complex queries need to be adjusted.

Tabnine 可以通过以下方式协助重构:

¥Tabnine can assist during refactorings by:

  • 识别代码中的模式并建议重构,同时保持一致性。

    ¥Identifying patterns in your code and suggesting refactorings while maintaining consistency.

  • 帮助在架构更改后更新数据库查询并减少手动工作量。

    ¥Helping update database queries after schema changes and reducing manual effort.

  • 提供函数重写以简化和优化逻辑。

    ¥Providing function rewrites to simplify and optimize logic.

  • 建议需要在整个代码库中处理的重大更改。

    ¥Suggesting breaking changes that need to be handled across your codebase.

示例:在模式更改后重构 Prisma 查询

¥Example: Refactoring a Prisma query after a schema change

提示

¥Prompt

重构此 Prisma 查询以支持使用用户模型中的 deletedAt 时间戳字段进行软删除。

¥Refactor this Prisma query to support soft deletion using a deletedAt timestamp field in the User model.

初始代码

¥Initial code

const users = await prisma.user.findMany();

重构代码

¥Refactored code

const users = await prisma.user.findMany({
where: { deletedAt: null }
});

生成种子脚本

¥Generating seeding scripts

Tabnine 如何提供帮助

¥How Tabnine helps

使用实际测试数据播种数据库可能很麻烦。真实的种子数据在开发过程中很有用,因为它可以让开发者在现实世界中使用应用时对应用有更好的印象。Tabnine 可以通过以下方式帮助数据库播种:

¥Seeding a database with realistic test data can be cumbersome. Realistic seed data is helpful during development because it gives the developer a better impression of the application when it's used in the real-world. Tabnine can help with database seeding by:

  • 根据模式和特定要求生成具有结构化种子数据的脚本。

    ¥Generating scripts with structured seed data based on the schema and with specific requirements.

  • 创建可用于测试应用的真实占位符数据。

    ¥Creating real-looking placeholder data that can be used to test the app.

  • 生成特定数据以涵盖边缘情况。

    ¥Generate specific data to cover edge cases.

示例:创建种子脚本

¥Example: Creating a seed script

提示

¥Prompt

生成 Prisma 种子脚本,用于填充用户、组织和订阅模型。

¥Generate a Prisma seed script for populating User, Organization, and Subscription models.

生成的代码

¥Generated code

import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

async function main() {
await prisma.organization.create({
data: {
name: "Prisma Corp",
slug: "prisma-corp",
subscription: {
create: {
plan: "PRO",
status: "ACTIVE"
}
},
users: {
create: [
{ name: "Alice Doe", email: "alice@prisma.io" },
{ name: "Bob Smith", email: "bob@prisma.io" }
]
}
}
});

console.log("Seed data created successfully");
}

main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});

Stay connected with Prisma

Continue your Prisma journey by connecting with our active community. Stay informed, get involved, and collaborate with other developers:

We genuinely value your involvement and look forward to having you as part of our community!