swift

Swift写服务端六:安装PostgreSQL并使用Vapor远

2022-06-15  本文已影响0人  狂奔的胖蜗牛

1.为什么安装PostgreSQL

因为Vapor官方推荐使用该数据库。

2.安装步骤

安装postgresql

sudo apt-get install postgresql

安装好后,默认已经开启了postgresql,使用service命令查看postgresql运行状态

yuhua@sweet-story-2:~$ service postgresql status
● postgresql.service - PostgreSQL RDBMS
   Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor prese
   Active: active (exited) since Mon 2022-06-13 21:45:58 EDT; 1min 48s ago
 Main PID: 2532 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 1175)
   CGroup: /system.slice/postgresql.service

postgresql安装好后,会创建出一个linux的用户,名字是:postgres,首次登录postgresql数据库时,必须使用该用户登录。所以使用该用户登录postgresql。

yuhua@sweet-story-2:~$ sudo -u postgres psql
[sudo] password for yuhua: 
psql (10.21 (Ubuntu 10.21-0ubuntu0.18.04.1))
Type "help" for help.

postgres=# 

创建用户的同时,还自动创建出了一个数据库: postgres,首次使用postgres用户登录时,自动连接上了该数据库。可以使用\conninfo命令查看连接信息。

postgres=# \conninfo
You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5432".

使用\l命令查看所有数据库信息。

postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(3 rows)

使用\du命令可以查看所有能够操作postgresql数据库的用户列表。

postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

由于数据库默认的postgres用户是没有设置密码的,我们需要给他设置密码

postgres=# \password postgres
Enter new password for user "postgres": 输入密码
Enter it again: 再次输入密码

密码改好后,创建出项目需要的数据库。

// 创建数据,注意末尾的分号
postgres=# CREATE DATABASE sample_code;
CREATE DATABASE
// 切换到创建的数据库
postgres=# \c sample_code
You are now connected to database "sample_code" as user "postgres".
// 查看是否连接正确
sample_code=# \conninfo
You are connected to database "sample_code" as user "postgres" via socket in "/var/run/postgresql" at port "5432".

退出postgresql

\q

3.设置nginx反向代理PostgreSQL

现在外部是无法连接到PostgreSQL,我们通过nginx反向代理让它能够被访问。将下面内容写入/etc/nginx/nginx.conf中,注意与http是同一级的。

stream {
        upstream pgsql {
                server 127.0.0.1:5432;
        }
        server {
                listen 12345;
                proxy_connect_timeout 30s;
                proxy_timeout 30s;
                proxy_pass pgsql;
        }
}

重启nginx。

sudo systemctl restart nginx

4.使用工具连接

接下来我使用VS Code的PostgreSQL插件进行连接,可以看到如下结果,说明连接成功了。


image.png

5.Vapor项目远程连接PostgreSQL

我没有在本机安装PostgreSQL,打算直接写代码的时候就远程连接然后进行编写。
首先,SampleCode项目Package.swift中添加Fluent和PostgreSQL Driver。


image.png
import PackageDescription

let package = Package(
    name: "SampleCode",
    platforms: [
       .macOS(.v12)
    ],
    dependencies: [
        // 💧 A server-side Swift web framework.
        .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
        .package(url: "https://github.com/vapor/fluent.git", from: "4.0.0"),
        .package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0")
    ],
    targets: [
        .target(
            name: "App",
            dependencies: [
                .product(name: "Vapor", package: "vapor"),
                .product(name: "Fluent", package: "fluent"),
                .product(name: "FluentPostgresDriver", package: "fluent-postgres-driver")
            ],
            swiftSettings: [
                // Enable better optimizations when building in Release configuration. Despite the use of
                // the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
                // builds. See <https://github.com/swift-server/guides/blob/main/docs/building.md#building-for-production> for details.
                .unsafeFlags(["-cross-module-optimization"], .when(configuration: .release))
            ]
        ),
        .executableTarget(name: "Run", dependencies: [.target(name: "App")]),
        .testTarget(name: "AppTests", dependencies: [
            .target(name: "App"),
            .product(name: "XCTVapor", package: "vapor"),
        ])
    ]
)

依赖拉取完毕后,增加模型类Menu.swift。

import Vapor
import Fluent

final class Menu: Model {
    // 数据库表名
    static let schema = "menu"
    
    // 使用UUID作为id,没有使用自增id,是为了适配NoSQL
    @ID
    var id: UUID?
    
    // 标题
    @Field(key: "title")
    var title: String
    
    // 父id,数据库字段名为super_id,名为superId,两者可以不一样。
    // 如果字段是可选的,需要使用OptionalField
    @OptionalField(key: "super_id")
    var superId: UUID?
    
    // 必须要有一个空的初始化方法
    init() {}
    
    // 自定义的初始化方法
    init(id: UUID? = nil, title: String, superId: UUID? = nil) {
        self.id = id
        self.title = title
        self.superId = superId
    }
}

然后增加数据库创建类CreateMenu.swift结构体。


import Fluent

struct CreateMenu: Migration {
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        database.schema("menu")
            .id()
            .field("title", .string, .required)
            .field("super_id", .uuid)
            .create()
    }
    
    func revert(on database: Database) -> EventLoopFuture<Void> {
        database.schema("menu").delete()
    }
}

有些数据不方便上传GitHub,我们可以放到环境变量中。在项目目录下创建.env文件夹,然后添加development和production文件。看名字就知道一个文件对应了一个开发环境。在文件内我们把数据库的地址,端口号,账号密码等信息写进去,为了安全,.env文件夹不要传到GitHub。


image.png

然后去configure.swift配置数据库。

import Vapor
import Fluent
import FluentPostgresDriver

// configures your application
public func configure(_ app: Application) throws {
    // uncomment to serve files from /Public folder
    // app.middleware.use(FileMiddleware(publicDirectory: app.directory.publicDirectory))

    // 连接数据库
    app.databases.use(.postgres(
        hostname: Environment.get("DATABASE_HOST") ?? "",
        port: Environment.get("DATABASE_PORT").flatMap(Int.init(_:)) ?? 0,
        username: Environment.get("DATABASE_USERNAME") ?? "",
        password: Environment.get("DATABASE_PASSWORD") ?? "",
        database: Environment.get("DATABASE_NAME") ?? ""
    ), as: .psql)
    
    // 创建表
    app.migrations.add(CreateMenu())
    // 设置打印等级
    app.logger.logLevel = .debug
    // 等待数据库操作完毕
    try app.autoMigrate().wait()
    
    // register routes
    try routes(app)
}

其中Environment.get()就是去读取配置文件的内容。如果是xcode运行的话,还需要把配置文件的内容在Run Scheme中配置一遍。


image.png

运行起来,然后去vs code的postgresql查看工具查看,可以看到数据库多出了一个表,表示项目正常运行,同时创建出了表。


image.png

6.更多PostgreSQL命令

psql -d database -U user -W 通过指定用户连接指定数据库
psql -h host -d database -U user -W 通过指定用户连接指定地址的指定数据库
psql -U user -h host “dbname=db sslmode=require”    通过ssh连接
\c dbname   切换数据库    
\l  列出所有数据库  
\dt 列出所有可用的数据库   
\d table_name   显示某个数据库的信息   
\dn 当前连接数据库信息
\df 当前连接数据库的方法
\dv 当前连接数据库的内容 
\du 当前连接数据库的用户 
SELECT version();   数据版本信息
\g  执行最后一条命令     
\s  展示命令列表
\s filename 保存历史命令 
\i filename 保存历史命令到文件 
\?  所有可用的命令
\h  命令帮助
\e  自定义命令 
\a  切换输出样式   
\H  切换输出为HTML样式
\q  退出
上一篇 下一篇

猜你喜欢

热点阅读