mac m1 electron生产环境使用prisma,sqlite

news2024/12/28 4:18:12

最近在用electron开发一个适合自己的小应用,技术选型中使用prisma和sqlite在进行数据存储,写这篇文章的目的就是用来记录下遇到的一些问题。

开发环境使用prisma

1、开发环境使用prisma非常的简单,只需要按照教程安装prisma,然后执行npx prisma init --datasource-provider sqlite 即可。脚本会生成schema文件
在schema文件中编写自己的模型。
开发环境中执行

npx prisma migrate dev --name xxxx

可以看到在我们的prisma目录下会有个迁移文件夹migrations,里面会生成我们的sql。这时候我们可以直接使用@prisma/client

import { PrismaClient } from '@prisma/client'
const prismaInstance = new PrismaClient()

可以用prismaInstance实例来进行数据库操作咯,这时候如果你使用的是ts并且安装了prisma的vs code插件你就会发现它的语法提示非常人性化,如果你之前有orm的基础就可以直接上手。

在生产环境中使用

一般情况下开发环境有nodejs环境,全局安装了prisma我们只需要把migrations文件夹拷贝到开发环境并且执行下面命令就行。

npx prisma migrate deploy

在electron中你使用electron-builder打包要怎么做才能正常使用prisma呢?

1、首先你得把migrations文件夹拷贝到安装包中,在package.json中使用extraResources来将我们所需要的migrations文件移入到安装包中。

"build": {
    "extraResources": [
      {
        "from": "prisma/migrations",
        "to": "resources/prisma/migrations"
      },
      {
        "from": "prisma/schema.prisma",
        "to": "resources/prisma/schema.prisma"
      }
    ]
}

这样打包后如果你打开 join(process.resourcesPath,'resources/prisma')这个路径就会发现migrations文件夹已经被移入,然后我们要执行npx prisma migrate delploy,但是在我们的electron生产环境中没有npx命令该怎么做,这时候我们就需要使用prisma提供的二进制来进行操作了。
根据不同的环境prisma会提供不同的二进制,比如我这边是mac m1,那么你就要在schema.prisma中加入以下内容,prisma运行过程中就会去下载drawin-arm64的二进制

generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "darwin-arm64"]
}

下载完你就会发现node_modules/@prisma/engines下会多出两个二进制文件

在这里插入图片描述

libquery是sql引擎,没有它就不能进行数据库操作。
schema就是我们刚才说的执行npx prisma migrate deploy的,可以理解为全局安装的prisma就是执行的这个二进制。
这样我们就可以直接使用二进制来执行我们的命令咯,前提是我们把二进制拷贝到了安装包内,你也可以使用extraResources属性,但我这边并没有写,因为electron一般会对文件都打包进asar二进制中,但是如果有些三方库的二进制打入二进制会出现一些意想不到的问题,所以可以在package.json设置asarUnpack,意味着不用吧这些文件进行二进制打包。

"build":{
 "asarUnpack": [
      "**/node_modules/prisma/**/*",
      "**/node_modules/@prisma/**/*"
    ]
}

我们怎么拿到那些不需要被打包的二进制呢?我们代码中怎么写呢,路径是什么呢?代码如下

const appUnpackedPath = app.getAppPath().replace('app.asar', 'app.asar.unpacked')
const schemePath = electronIsDev ? resolve(__dirname, '../node_modules/@prisma/engines/schema-engine-darwin-arm64') : resolve(appUnpackedPath, './node_modules/@prisma/engines/schema-engine-darwin-arm64')

上面是对开发环境进行了判断,读者可以自行处理,appUnkpackedPath就是我们的二进制存放路径。
我们可以开发编写一套统一的处理代码,这套也是我从github某篇issue上直接拿下来的。

export async function runPrisma(command: string[]) {
  try {
    const exitCode = await new Promise((r, _) => {
      const prismaPath = resolve(electronIsDev ? resolve(__dirname, '../node_modules') : resolve(appUnpackedPath, './node_modules'), 'prisma', 'build', 'index.js')
      logger.info(process.cwd(), 'cwd')
      const child = fork(prismaPath, command, {
        cwd: electronIsDev ? process.cwd() : join(appUserPath, 'resources'),
        env: {
          ...process.env,
          DATABASE_URL: process.env.DATABASE_URL,
          PRISMA_QUERY_ENGINE_LIBRARY: queryPath,
          PRISMA_SCHEMA_ENGINE_BINARY: schemePath,
        },
        stdio: 'pipe',
      })

      child.on('message', (msg) => {
        logger.info(msg)
      })

      child.on('error', (err) => {
        logger.error('Child process got error:', err)
      })

      child.on('close', (code) => {
        logger.info(code)
        r(code)
      })

      child.stdout?.on('data', function (data) {
        // console.log(data)

        logger.info('prisma: ', data.toString())
      })

      child.stderr?.on('data', function (data) {
        logger.error('prisma: ', data.toString())
      })
    })

    if (exitCode !== 0) {
      throw Error(`command ${command} failed with exit code ${exitCode}`)
    }

    return exitCode
  } catch (e) {
    logger.error(e)
    throw e
  }
}

我们执行只需要传入参数进行即可

要注意我们的命令执行路径,也就是cwd参数要传入正确,要确保路径下面的文件内容格式符合prisma要求,prisma/migrations/xx类似这样即可

runPrisma(['migrate', 'deploy'])

上面代码中还有个queryPath,这个path是用来获取执行sql的引擎的,如果没有他我们就不能进行数据库操作,开发环境不需要我们指定引擎的二进制,但是在electron中需要我们来指定一下,有两种方法一种是使用环境变量process.env.PRISMA_QUERY_ENGINE_BINARY = queryPath,但是这种方法我这一直没成功,所以在github上找到了一种隐藏api方式来直接指定

const prismaInstance = new PrismaClient({
  __internal: {
    engine: {
      binaryPath: queryPath,
    },
  },
} as any)

这个__internal是一个非标准api,但是使用了发现能正常执行了。如果不指定就会一直报错
Can not spawn Query Engine when using Electron

结语

最后寻找感兴趣开发小工具的小伙伴一起来开发,目前我给这个产品取名Ew Box,Everything You Want,技术栈使用如下:

  • vite
  • electron
  • react,react-router
  • prisma
  • sqlite
  • tailwindcss
  • shadcn/ui
  • koa

对以上技术感兴趣,还有一些不错的idea的小伙伴都可以加入哟,后续可以使用你感兴趣的任何技术栈都可以集成其中
产品没有盈利目的,都是些简单的小功能点,做一款适合自己的小工具,就单纯想扩展或者提升技术面的小伙伴可以尝试加入哟
目前产品功能有压缩图片/密码箱/todo日历等功能,有想法的朋友可以一起加入哟。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2167555.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue嵌套路由刷新页面空白问题

问题描述 在vue项目开发中遇到这样一个问题,在history模式下通过页面点击路由跳转可以打开页面,但是在当前页面刷新就空白了,如下: 点击路由跳转页面是有的 刷新页面就空白 代码 {path: "/home",name: "home&qu…

TreeMap源码详解

优质博文:IT-BLOG-CN 背景:昨天有人问我,他想将Map中的Key按照顺序进行遍历,我说直接使用keySet方法获取到Set集合,因为它是集成Collection接口,所以包含了sort方法后遍历取value值即可。但当看到TreeMap的…

差旅报销的数智化转型 以分贝通为例

企业差旅报销的数智化转型之所以势在必行,源于传统差旅报销方式在效率、合规性和成本控制等方面存在严重不足。作为服务企业的一体化差旅报销管理平台,分贝通结合数千家合作伙伴的实际案例为企业提供定制化的差旅报销数智化解决方案,帮助企业…

【Python报错已解决】AttributeError: ‘tuple‘ object has no attribute ‘log_softmax‘

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

CentOS 7 中安装 docker 环境

作者:程序那点事儿 日期:2023/02/15 02:31 官网地址 官网文档 docker三种网络模式 Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10, CentOS 7 满足最低内核的要求。 Docker 分为 CE 和 EE 两大版本。CE 即社区…

前端开发必备:实用Tool封装工具类方法大全

程序员必备宝典网站https://tmxkj.top/#/ 1.判断空值 /*** 判断是否是空值*/ export function isEmpty(value) {if (typeof value string) {return value.length 0 || value "";} else if (typeof value number) {return value 0;} else if (Array.isArray(va…

TypeScript 设计模式之【抽象工厂模式】

文章目录 抽象工厂模式:一个神奇的玩具制造商主要思想:玩具制造商的秘密这个制造商有什么好处和坏处?如何打造这个神奇的玩具制造商?代码实现案例抽象工厂模式主要优点抽象工厂模式主要缺点抽象工厂模式适用场景总结 抽象工厂模式:一个神奇的玩具制造商 想象一下&#xff0c…

(done) 声音信号处理基础知识(7) (Understanding Time Domain Audio Features)

参考:https://www.youtube.com/watch?vSRrQ_v-OOSg&t1s 时域特征包括: 1.幅度包络 2.均方根能量 3.过零率 振幅包络的定义:一个 frame 里,所有采样点中最大的振幅值 一个形象的关于振幅包络的可视化解释如下:…

基于SpringBoot + Vue的大学生日常消费管理系统设计与实现

文章目录 前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S 四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论 五、项目代码参考六、数据库代码参考七、项目论文示例结语 前言 💛博主介绍&a…

fiddler抓包07_抓IOS手机请求

课程大纲 前提:电脑和手机连接同一个局域网 (土小帽电脑和手机都连了自己的无线网“tuxiaomao”。) 原理如下: 电脑浏览器抓包时,直接就是本机网络。手机想被电脑Fiddler抓包,就要把Fiddler变成手机和网络…

浅拷贝和深拷贝(Java 与 JavaScript)

一、Java 浅拷贝和深拷贝 在Java中,浅拷贝和深拷贝的主要区别在于对对象的引用和内容的复制方式。 浅拷贝 Java 的类型有基本数据类型和引用类型,基本数据类型是可以由 CPU 直接操作的类型,无论是深拷贝还是浅拷贝,都是会复制出…

ANSYS Workbench晶体结构Voronoi泰森多边形建模

在ANSYS Workbench内建立包含晶格及晶格边界在内的晶体结构模型,可用于模拟多种物理现象及材料行为。晶格模型适用于研究微观尺度下的材料性质,以及它们如何影响宏观性能,如进行金属晶体结构建模及断裂的模拟等。 晶体结构模型可采用CAD Vo…

fastapp-微信开发GPT项目第一课

0. 开发说明 在学习开发本项目之前,必须保证有以下知识储备和环境工具。 技术栈说明python>3.9、pydantic>2.7.1python基础,http协议fastapi>0.111.0web协程异步框架,有web开发基础,异步编程,类型标注[pyth…

银河麒麟操作系统中查看动态库函数的方法

银河麒麟操作系统中查看动态库函数的方法 1、查看单个动态库中的函数2、查找特定函数位于哪个动态库中 💖The Begin💖点点关注,收藏不迷路💖 在Linux系统,包括银河麒麟操作系统中,动态库(.so文件…

单片机项目合集列表与专栏说明——Excel合集列表目录查阅(持续更新)

阿齐Archie《单片机项目合集》专栏项目 为方便查找本专栏的项目,特整理Excel合集列表供查阅(可搜索或按系列查找) 持续更新链接如下: 阿齐单片机项目合集 (kdocs.cn)https://www.kdocs.cn/l/cmrxCxJN05YN 打开链接如下Exce表所…

【LeetCode:219. 存在重复元素 II + 哈希表】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

人工智能领域-----机器学习和深度学习的区别

机器学习和深度学习都是人工智能领域中的重要概念,它们之间存在以下一些区别: 一、定义与概念 机器学习: 是一种让计算机自动学习和改进的方法,通过从数据中学习模式和规律,从而能够对新的数据进行预测或决策。涵盖了…

Android compose 的基本环境搭建

1.创建项目 导入版本 1.gradle/libs.versions.toml [versions] accompanistPermissions "0.36.0" agp "8.5.0-beta01" coilCompose "2.7.0" constraintlayoutComposeVersion "1.0.1" hiltAndroid "2.51.1" hiltNavi…

git其他人有改动,自己这边不要pull,先stash一下,pull了然后apply自己的stash。

git其他人有改动,自己这边不要pull,先stash一下,pull了然后apply自己的stash, git 冲突了怎么处理处理? git会提示冲突的文件 On branch experiments You have unmerged paths.(fix conflicts and run "git comm…