上下文
我正在使用aws-node-typescript
示例无服务器框架。我的目标是将普里斯马集成到其中。
到目前为止,我已经:
serverless create
在本地创建项目prisma
,运行了prisma init
,创建了基本的User
模型,并成功地运行了prisma migrate dev
users
函数创建第二个hello
函数serverless deploy
部署该函数PrismaClient
时,我得到一个内部服务器错误,该函数记录这个错误:"ENOENT: no such file or directory, open '/var/task/src/functions/users/schema.prisma'"
我的项目结构如下:
.
├── README.md
├── package-lock.json
├── package.json
├── prisma
│ ├── migrations
│ │ ├── 20221006113352_init
│ │ │ └── migration.sql
│ │ └── migration_lock.toml
│ └── schema.prisma
├── serverless.ts
├── src
│ ├── functions
│ │ ├── hello
│ │ │ ├── handler.ts
│ │ │ ├── index.ts
│ │ │ ├── mock.json
│ │ │ └── schema.ts
│ │ ├── index.ts
│ │ └── users
│ │ ├── handler.ts
│ │ └── index.ts
│ └── libs
│ ├── api-gateway.ts
│ ├── handler-resolver.ts
│ └── lambda.ts
├── tsconfig.json
└── tsconfig.paths.json
另外,下面是users
函数的处理程序: ts
import { formatJSONResponse } from '@libs/api-gateway';
import { middyfy } from '@libs/lambda';
import { PrismaClient } from '@prisma/client'
const users = async (event) => {
console.log(`Instantiating PrismaClient inside handler ...`)
const prisma = new PrismaClient()
return formatJSONResponse({
message: `Hello, ${event.queryStringParameters.name || 'there'} welcome to the exciting Serverless world!`,
event,
});
};
export const main = middyfy(users);
出现这个问题是因为为了实例化PrismaClient
,schema.prisma
文件需要成为应用程序包的一部分。具体来说,它需要在/var/task/src/functions/users/
中,正如错误消息所指示的那样。
我已经在我的package.patterns
文件中调整了serverless.ts
选项,如下所示:
package: { individually: true, patterns: ["**/*.prisma"] },
问题
这样,上传到AWS的包在根目录中包含了prisma
目录,这是运行sls package
后的.serverless
文件夹(我在这里解压缩了users.zip
以便查看其内容):
.
├── cloudformation-template-create-stack.json
├── cloudformation-template-update-stack.json
├── hello.zip
├── serverless-state.json
├── users
│ ├── prisma
│ │ └── schema.prisma
│ └── src
│ └── functions
│ └── users
│ ├── handler.js
│ └── handler.js.map
└── users.zip
我还可以确认我的AWS Lambda的部署版本具有相同的文件夹结构。
如何使用我的users/prisma/schema.prisma
文件中的patterns
将该patterns
文件移动到users/src/functions/users
中?
发布于 2022-10-07 14:57:33
我找到了一个(很难看的)解决方案。如果有人能想到一个更优雅的答案,我仍然非常乐意给你一个正确答案的分数。
"ENOENT: no such file or directory, open '/var/task/src/functions/users/schema.prisma'"
误差的求解
为了解决这个问题,我采取了一种非常天真的方法,将schema.prisma
文件从prisma
目录手动复制到src/functions/users
中。下面是我现在拥有的文件结构:
.
├── README.md
├── package-lock.json
├── package.json
├── prisma
│ ├── migrations
│ │ ├── 20221006113352_init
│ │ │ └── migration.sql
│ │ └── migration_lock.toml
│ └── schema.prisma
├── serverless.ts
├── src
│ ├── functions
│ │ ├── hello
│ │ │ ├── handler.ts
│ │ │ ├── index.ts
│ │ │ ├── mock.json
│ │ │ └── schema.ts
│ │ ├── index.ts
│ │ └── users
│ │ ├── schema.prisma
│ │ ├── handler.ts
│ │ └── index.ts
│ └── libs
│ ├── api-gateway.ts
│ ├── handler-resolver.ts
│ └── lambda.ts
├── tsconfig.json
└── tsconfig.paths.json
这显然是解决这个问题的可怕方法,因为我现在在不同的位置上有两个Prisma模式文件,并且必须确保在更改了prisma/schema.prisma
中的原始文件以保持它们的同步之后,始终更新prisma/schema.prisma
中的一个。
一旦我复制了这个文件并重新部署,schema.prisma
文件就在AWS的正确位置上了,错误消失了,PrismaClient
可以被实例化了。
然后,我在处理程序中添加了一个简单的Prisma客户端查询:
const users = async (event) => {
console.log(`Instantiating PrismaClient inside handler ...`)
const prisma = new PrismaClient()
const userCount = await prisma.user.count()
console.log(`There are ${userCount} users in the database`)
return formatJSONResponse({
message: `Hello, ${event.queryStringParameters.name || 'there'} welcome to the exciting Serverless world!`,
event,
});
};
export const main = middyfy(users);
..。这一次,在查询引擎方面遇到了一个新错误:
Invalid `prisma.user.count()` invocation:
Query engine library for current platform \"rhel-openssl-1.0.x\" could not be found.
You incorrectly pinned it to rhel-openssl-1.0.x
This probably happens, because you built Prisma Client on a different platform.
(Prisma Client looked in \"/var/task/src/functions/users/libquery_engine-rhel-openssl-1.0.x.so.node\")
Searched Locations:
/var/task/.prisma/client
/Users/nikolasburk/prisma/talks/2022/serverless-conf-berlin/aws-node-typescript/node_modules/@prisma/client
/var/task/src/functions
/var/task/src/functions/users
/var/task/prisma
/tmp/prisma-engines
/var/task/src/functions/users
To solve this problem, add the platform \"rhel-openssl-1.0.x\" to the \"binaryTargets\" attribute in the \"generator\" block in the \"schema.prisma\" file:
generator client {
provider = \"prisma-client-js\"
binaryTargets = [\"native\"]
}
Then run \"prisma generate\" for your changes to take effect.
Read more about deploying Prisma Client: https://pris.ly/d/client-generator
Query engine library for current platform \"rhel-openssl-1.0.x\" could not be found.
误差的求解
我非常熟悉Prisma,知道Prisma客户端依赖于专门为Prisma客户端运行的平台构建的查询引擎二进制文件。这可以通过我的Prisma模式中的binaryTargets
块上的generator
字段进行配置。AWS的目标是rhel-openssl-1.0.x
。
因此,我相应地调整了schema.prisma
文件(在两个位置):
generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "rhel-openssl-1.0.x"]
}
之后,我运行npx prisma generate
来更新node_modules
中生成的Prisma客户机。
然而,这还没有解决错误,问题仍然是Prisma客户端找不到查询引擎二进制。
因此,当schema.prisma
文件丢失时,我遵循了与它相同的方法:
src/functions/users
中(这次是从它在node_modules/.prisma/libquery_engine-rhel-openssl-1.0.x.so.node
中的位置)serverless.ts
:package:{serverless.ts
:true,serverless.ts
:“**/*.true”,在重新部署和测试该功能之后,又发生了另一个错误:
Invalid `prisma.user.count()` invocation:
error: Environment variable not found: DATABASE_URL.
--> schema.prisma:11
|
10 | provider = \"postgresql\"
11 | url = env(\"DATABASE_URL\")
|
Validation Error Count: 1
Environment variable not found: DATABASE_URL.
误差的求解
这一次,非常简单,我进入了https://us-east-1.console.aws.amazon.com/lambda/home?region=us-east-1#/functions/aws-node-typescript-dev-users?tab=configure
的AWS控制台,通过Console UI添加了一个DATABASE_URL
env,指向铁路上的Postgres实例:
发布于 2022-12-01 19:24:17
一个选项是在copy-webpack-plugin中使用webpack并更改应用程序的结构,将所有处理程序放在处理程序文件夹中。
文件夹结构
.
├── handlers/
│ ├── hello.ts
│ └── ...
└── services/
├── hello.ts
└── ...
webpack.config.js
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require("path");
// const nodeExternals = require("webpack-node-externals");
const CopyPlugin = require("copy-webpack-plugin");
const slsw = require("serverless-webpack");
const { isLocal } = slsw.lib.webpack;
module.exports = {
target: "node",
stats: "normal",
entry: slsw.lib.entries,
// externals: [nodeExternals()],
mode: isLocal ? "development" : "production",
optimization: { concatenateModules: false },
resolve: { extensions: [".js", ".ts"] },
output: {
libraryTarget: "commonjs",
filename: "[name].js",
path: path.resolve(__dirname, ".webpack"),
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/,
},
],
},
plugins: [
new CopyPlugin({
patterns: [
{
from: "./prisma/schema.prisma",
to: "handlers/schema.prisma",
},
{
from: "./node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node",
to: "handlers/libquery_engine-rhel-openssl-1.0.x.so.node",
},
],
}),
],
};
如果您需要在组装包之前运行npx生成,您可以使用插件(放在webpack之前):
plugins:
- serverless-scriptable-plugin
- serverless-webpack
custom:
scriptable:
hooks:
before:package:createDeploymentArtifacts: npx prisma generate
webpack:
includeModules: false
受抚养人:
npm install -D webpack serverless-webpack webpack-node-externals copy-webpack-plugin serverless-scriptable-plugin
https://stackoverflow.com/questions/73985623
复制相似问题