美文网首页swift
Swift写服务端六:安装PostgreSQL并使用Vapor远

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

作者: 狂奔的胖蜗牛 | 来源:发表于2022-06-15 13:56 被阅读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。

    • 不需要管这个linux用户,该用户是无法登录的。
    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  退出
    

    相关文章

      网友评论

        本文标题:Swift写服务端六:安装PostgreSQL并使用Vapor远

        本文链接:https://www.haomeiwen.com/subject/sstzmrtx.html