无法在 Vapor 项目中连接我的 MySQL 数据库

Posted

技术标签:

【中文标题】无法在 Vapor 项目中连接我的 MySQL 数据库【英文标题】:Can`t connect my MySQL database in Vapor project 【发布时间】:2019-01-16 08:51:50 【问题描述】:

我是 Vapor 的新手,我想尝试连接我的 mysql 数据库。我在官方文档上找到了怎么做,但是当我尝试发送查询时,它会抛出一个错误:

No services are available for 'DatabaseConnectionPoolCache'. (Container.swift:112)

我只是从文档中复制粘贴代码,但它不起作用。有人可以帮我找出原因吗?

我在 Mojave 上有 MySQL@5.7。实际上简单的请求效果很好,例如:

router.get("hey")  req in
    return "Stas, hey"

configure.swift 中的代码:

import FluentSQLite
import MySQL
import Vapor

/// Called before your application initializes.
public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws 
    /// Register providers first
    try services.register(FluentSQLiteProvider())
    try services.register(MySQLProvider())

    /// Register routes to the router
    let router = EngineRouter.default()
    try routes(router)
    services.register(router, as: Router.self)

    /// Register middleware
    var middlewares = MiddlewareConfig() // Create _empty_ middleware config
    /// middlewares.use(FileMiddleware.self) // Serves files from `Public/` directory
    middlewares.use(ErrorMiddleware.self) // Catches errors and converts to HTTP response
    services.register(middlewares)

    // Configure a SQLite database
    let sqlite = try SQLiteDatabase(storage: .memory)

    /// Register the configured SQLite database to the database config.
    var databases = DatabasesConfig()
    databases.add(database: sqlite, as: .sqlite)
    services.register(databases)

    /// Configure migrations
    var migrations = MigrationConfig()
    migrations.add(model: Todo.self, database: .sqlite)
    services.register(migrations)

    //Configure a MySQL database
    let mysql = try MySQLDatabase(config: MySQLDatabaseConfig(
        hostname: "127.0.0.1",
        port: 3306,
        username: "root",
        password: "7374",
        database: "WORK_TIME"))

    ///Register to the congig
    var mysqlDatabases = DatabasesConfig()
    mysqlDatabases.add(database: mysql, as: .mysql)
    services.register(mysqlDatabases) 

我在 main.swift 中的查询:

public struct MySQLVersion: Codable 
    let version: String


router.get("sql")  req in
    return req.withPooledConnection(to: .mysql) conn in
        return conn.raw("SELECT @@version as version")
            .all(decoding: MySQLVersion.self)
        .map  rows in
            return rows[0].version
    

它应该返回我的 MySQL 版本,但它会抛出一个奇怪的错误。

【问题讨论】:

【参考方案1】:

您的问题是原始项目模板中存在一些剩余的 SQLite 内容。

首先从您的Package.swift 文件中删除fluent-sqlite 依赖项,并从任何目标依赖项中删除FluentSQLite 目标。然后在终端中运行swift package update(如果你使用Xcode,则运行vapor xcode)。

现在您已经从项目中删除了 FluentSQLite 依赖项,您应该能够按照编译器错误来解决您的问题。以下是我找到的:


import FluentSQLite
import MySQL

应该是:

import FluentMySQL

try services.register(FluentSQLiteProvider())
try services.register(MySQLProvider())

应该是

try services.register(FluentMySQLProvider())

删除这个,因为您使用的是 MySQL 而不是 SQLite:

// Configure a SQLite database
let sqlite = try SQLiteDatabase(storage: .memory)

/// Register the configured SQLite database to the database config.
var databases = DatabasesConfig()
databases.add(database: sqlite, as: .sqlite)
services.register(databases)

migrations.add(model: Todo.self, database: .sqlite)

应该是

migrations.add(model: Todo.self, database: .mysql)

我认为这涵盖了所有内容。您的 /sql 路由现在应该可以工作了。

【讨论】:

不幸的是,同样的错误。可能,迁移中有错误吗? (我想是因为那里有.sqlitevar migrations = MigrationConfig()migrations.add(model: Todo.self, database: .sqlite)services.register(migrations) @StanislavMarynych 是的,我错过了。 Todo 迁移应使用 .mysql。我会将其添加到我的答案中。 哦,很抱歉我发现了我的错误,现在可以了) 这是一个愚蠢的错误,我不得不在routes.swift 中写我的路线,而不是在main.swift 中。感谢您的帮助! @StanislavMarynych 太好了!您可以发布自己的问题答案并在允许后接受(您必须等待 24 小时左右)。【参考方案2】:

要解决这个问题,你应该从原始项目中删除所有剩余的 SQLite 东西,并且必须在 routes.swift 中编写你的路由

【讨论】:

以上是关于无法在 Vapor 项目中连接我的 MySQL 数据库的主要内容,如果未能解决你的问题,请参考以下文章

我应该在 Vapor 项目的哪里添加我自己的 Markdown 文件?

Vapor Mysql没有构建

国内首个完整的 Swift 服务端开源项目及详解 - 基于 Vapor 3 框架

Docker:无法连接 Spring Boot 和 MYSQL

如何在Vapor 3中从JSON响应中保存父子关系

Mysql中Sleep进程连接数过多问题解决