0%

Prisma 命令行

Prisma CLI 提供了一套完整的命令来支持数据库的开发、迁移和维护工作。下面我将主要命令按照开发流程和环境进行分类说明,并特别注明在 PostgreSQL 数据库下的注意事项。

核心命令速览

下表汇总了Prisma的核心CLI命令及其主要用途,你可以对其有个快速的整体印象。

命令 主要用途 典型使用场景
prisma init 初始化一个新的Prisma项目结构。 新项目搭建,创建schema.prisma.env文件模板。
prisma generate 根据数据模型生成Prisma Client(类型安全的查询客户端)。 每次修改schema.prisma文件后都必须运行,以使更改生效于代码。
prisma db pull 从现有数据库提取结构,生成Prisma数据模型(反向工程)。 接管一个已有的数据库项目。
prisma db push 将Prisma数据模型中的更改直接同步到数据库,不生成迁移文件 仅用于开发环境的快速原型设计,切勿在生产环境使用。
prisma migrate dev 在开发环境中,创建并应用数据库迁移文件,同时生成Client。 开发阶段管理所有数据库结构变更的主要命令
prisma migrate deploy 将已生成的迁移文件应用到生产环境数据库。 在生产服务器上部署最新的数据库结构变更。
prisma migrate resolve 手动解决迁移冲突,标记某个迁移为已应用或已回滚。 migrate deploy失败,数据库状态与迁移历史不一致时。
prisma migrate reset 重置整个数据库,清空所有数据并重新应用所有迁移。 开发或测试环境中,需要回归到初始干净状态时。
prisma studio 启动一个Web界面,用于直观地查看和编辑数据库中的数据。 开发调试时快速查看、修改数据。
prisma db seed 运行种子脚本,为数据库填充初始数据。 migrate reset后或首次初始化数据库后自动填充基础数据。

执行prisma migrate系列命令,会产生数据记录表_prisma_migrations,记录每次迁移的详细信息,包括名称、开始时间、结束时间、状态等。Prisma在数据库中的id是迁移文件的MD5哈希值,所以迁移结束后手动修改迁移文件也会报不一致的错误。

Read more »

如何Vibe Coding?

首先要要明白编程Agent的原理: 大模型+Tools+Prompt。理解后就可以有的放矢,进行Vibe Coding了。

意图一致

询问Agent: “我想做xxxx,.说出你的理解”。仔细观察大模型的输出,看看其是否完全理解你的意图,并且进行必要的调整,直至完全符合你的意图。其实从编程工具的最后一步动作:编写文件,来思考的话,往前推导它的上一步是决定如何修改什么,所以和人类编程过程是类似的。理解需求->修改什么->在哪里修改。所以你想掌握vibe coding的质量,就从前两步介入,文件修改完全不需要介入。

方案讨论

常用的问题:

  1. 当前业内推荐的方案或者最佳实践是什么?
  2. 你的实现是哪种方案?为什么是这个方案?
  3. 为什么在这个场景下这个是最佳方案?
  4. 如果采用这个方案,该注意什么?
  5. 当前方案有哪些潜在的问题?
  6. 如何提升性能?

策略

  1. 每有一个Feature完成,就提交commit
  2. 使用CI自动部署
  3. 先实现功能,再优化,不要积累技术债,也不要过早优化( 进二退一)

注意事项

  1. 不要说”撤销“,因为AI会可能做git checkout操作,那是非常危险的。所以说”改回之前的代码“,而不说”撤销“。

1. Vercel

Vercel即支持Next.js也支持express,但是注意它们都是无状态的serverless。不支持长连接,如websocket。

接下来介绍下moonorepo的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"version": 2,
"builds": [
{
"src": "backend/api/index.ts",
"use": "@vercel/node"
},
{
"src": "frontend/next.config.js",
"use": "@vercel/next"
}
],
"rewrites": [
{
"source": "/api/(.*)",
"destination": "backend/api/index.ts"
},
{
"source": "/(.*)",
"destination": "frontend/$1"
}
]
}

这里注意使用了rewrites,不用使用routes,因为routes不支持动态链接,这个是好坑的,我在上面浪费了不少时间。混合渲染注意事项,后端渲染拿不到windows和localstoreage,所以这里要注意使用前端渲染去获取。更好的比方是,后端渲染返回了html,前端渲染使用JS。

Read more »

1. Mac上使用Docker安装MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
# 启动容器
docker run --name=mysql8 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql/mysql-server:8.0.32

# 进入容器
docker exec -it mysql8 mysql -uroot -p

# 修改root的localhost
mysql> update user set host='%' where user='root';

FLUSH PRIVILEGES;

# 更新密码算法,让Navicat可以连接
ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';

最后这个修改密码算法是必要的,不然会出现这个错误Public Key Retrieval is not allowed

Read more »

1. os.getcwd()

os.getcwd()返回工作目录,工作目录(Working Directory)是指当前用户或程序正在其中执行命令或访问文件的目录。在操作系统中,当你打开一个命令行界面(如终端、命令提示符)或运行一个程序时,都有一个与之关联的工作目录。这个目录是相对于该环境而言的当前位置,用于解析相对路径。
os.getcwd() 函数是 Python 标准库 os 模块中的一个函数,用于获取当前工作目录的绝对路径。这个函数通过查询操作系统来确定当前进程的工作目录,并将其作为一个字符串返回。
具体来说,os.getcwd() 如何确定工作目录,取决于操作系统提供的机制。在 Unix-like 系统(如 Linux 和 macOS)中,这通常涉及到查询当前进程的环境信息,该信息中包含了工作目录的路径。在 Windows 系统中,机制可能有所不同,但同样依赖于操作系统提供的API来查询当前进程的工作目录。

当 Python 程序(或 Python 交互式解释器)启动时,它的工作目录通常是启动该程序或解释器的那个目录。但是,在程序执行过程中,可以使用 os.chdir(path) 函数来改变工作目录,这时 os.getcwd() 返回的将是新的工作目录路径。
需要注意的是,os.getcwd() 返回的是绝对路径,这意味着它是一个从根目录开始的完整路径,不受当前工作目录的相对位置影响。这对于需要精确处理文件路径的程序来说是非常有用的。

所以python返回的工作目录是执行python命令的那个目录,所以这个目录很重要,不能随便用来删除目录,我不小心就把自己的源码目录给删除了,还好有GitHub。

2. timezone

python有第三方库pytz,python 3.9版本以上有一个自带的库zoneinfo。我必须吐槽一下,这个timezone库就这么不重视吗,这么晚才有。

2.1 不带timezone的创建方法

1
2
3
date1= datetime.now()
date2 = datetime.strptime(str, '%Y-%m-%d')
date3 = datetime(2023, 4, 1, 10, 0, 0)

这3种都是不带timezone,但是有个地方要注意,date1虽然没带,但是如果打印它,是当前的系统timezone下的时间,而非UTC时间,所以就是它没有这个tzinfo的属性,但是就是用了。

2.2 带有timezone的创建方法

1
2
3
4
5
6
tz = pytz.timezone('Asia/Shanghai')
date1= datetime.now(pytz.utc) # 或者 datetime.now(tz)

date2 = datetime.strptime(str, '%Y-%m-%d')
local_date = tz.localize(date2)
utc_date = pytz.utc.localize(date2)

这里就是给datetime.now一个tzinfo,无论给它什么样的tzinfo,最近它们的本质还是一样的,都是同一个时间,不同点只是tzinfo不同。注意localize只能对没有tzinfo的值设置,而replace没有这个限制。
尽管实参一样,但是local_date和utc_date的表示时间却是不一样的,因为date2原来没有tzinfo,调用了不同的tzinfo.localize方法后,产生的时间就是不一样的,所以这需要知道你的实参的timezone是什么,才能正确的给它设置timezone。

2.3 timezone转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 将UTC时间转换为上海时间
# 第一种方法
local_date = utc_date.astimezone(tz) # 结果正确

# 第二种方法
from zoneinfo import ZoneInfo
zone_info = ZoneInfo('Asia/Shanghai')
local_date2 = utc_date.astimezone(zone_info) # 结果正确

# 第三种方法
local_date3 = datetime.now(tz=pytz.utc).replace(tzinfo=zone_info).astimezone(shanghai_tz) #结果正确
local_date4 = datetime.now(tz=pytz.utc).replace(tzinfo=pytz.utc).astimezone(shanghai_tz) #结果正确
local_date5 = datetime.now().replace(tz=shanghai_tz) #结果错误,虽然按照2.1的创建方法date.now其实使用了tzinfo的信息,但是结果是不对。
local_date6 = datetime.now(tz=shanghai_tz).replace(tzinfo=shanghai_tz).astimezone(shanghai_tz) #结果错误
print(local_date5) # local_date4 2024-09-04 19:02:43.948018+08:06 这个后面带有06分钟,是个什么意思?

当我们有一个带有timezone的时间,想转为另一个timezone的时间,从时间本身来讲,它们是一样的,只不过是影响了表现形式。这里的作用就是给用户看的时候,他能理解这个是他的时区的时间,所以这种转换就是为了输出可视化字符串。
由于replace过于粗暴,所以还是最好别用了, replace中传入pytz.tzinfo就有bug。实在要用就用zoneinfo,不要用pytz。

2.4 时间比较

时间比较需要注意的是,要么两个时间都不带timezone,要么都带,不能一个带一个不带。所以推荐都带,两个时间相减时,得到timedelta。因为有些服务的API返回的date是带有timezone的,所以最好我们自己的时间也带上。

判断字符串相等

需要考虑到空值的情况

1
2
3
4
5
6
7
8
# 当$a是空值的时候,会有问题,因为这个语句变为了 if [ == "abc" ]; then
if [ $a == "abc" ]; then
echo $a
fi
# 解决方法是加上另外一个大括号
if [[ $a == "abc" ]]; then
echo $a
fi

字符串要双引号

1
2
3
4
5
A="abc"
B="$A 123"
C=$A + "123" # 错误,结果是:abc+123
D='${A}123' # 错误,单引号不能引用变量,结果:${A}123
E="${A}123" # 结果:abc123
Read more »

由于Mac的磁盘空间不足,需要时常清理一下。

1. XCode

Derived Data是一个文件夹,它默认情况下位于:~/Library/Developer/Xcode/DerivedData。它是Xcode存储各种中间构建结果、生成索引等的位置,这个文件夹通常会很大,清理后会回收不少空间。你可以在Xcode的preferences中设置Derived Data的位置。清理之后构建首次构建项目的时候可能会增加构建时间。但是这不影响正常使用。而且还可以回收更多自由的空间内存。

1
2
3
rm -rf ~/Library/Developer/Xcode/DerivedData/*
# 可以定期执行清楚缓存
alias xcode-clean-derived="rm -rf ~/Library/Developer/Xcode/DerivedData/*"
Read more »

1. 概述

Jaeger有几个组件:

  • Jaeger-agent:一个无状态的进程,负责接收并转发数据到Jaeger-collector。
  • Jaeger-collector:一个有状态的进程,负责接收并聚合数据,以及提供查询服务。
  • Jaeger-query:一个有状态的进程,负责接收查询请求,并返回结果。
Read more »

Jenkins 安装

官方说 java -jar jenkins.war是推荐的方式,意外的是tomcat不推荐。原因是jenkins内置了web服务器Jetty, 而Jetty使用了Servlet, 所以高版本的tomcata不兼容,会报一个诡异的错误: “The requested resource [/jenkins] is not available”。

排查原因:

  • 缺少$JRE_HOME,最后发现不是这个原因。Tomcat只需要设置$JAVA_HOME
  • 修改JVM版本,在bin/catalina.sh中, export $JAVA_HOME和$JRE_HOME, 最后发现不是这个问题,JDK11,17都可以
  • 修改Tomcat版本,把Tomcat从10降级到9版本就可以了。
    最后兼容的tomcat是tomcat9.

Tomcat修改账号,conf/tomcat-users.xml, 增加一个用户名和密码,并且赋权限manager-ui。是的,这个tomcata的管理权限还是不要在pro环境开,不然有风险。

把下载后的jenkins.war放到tomcata的安装目录下的webapp目录下面,不需要解压,tomcat会自己解压。

启动Tomcat: catalina.sh start,这个是后台运行,关闭shell/session也不印象Tomcata运行。
关闭Tomcat: catalina.sh stop,每次修改配置文件后,都需要重启。

1. iOS结构

iOS

iOS操作系统从上到下依次是:

交互层 Cocoa Touch
媒体层 Media
核心服务层 Core Services
操作系统层 Core OS
内核和设备服务层 Kernel

Read more »