
This video is only available to subscribers. Start a subscription today to get access to this and 472 other videos.
Setting up a Database with Fluent
This episode is part of a series: Server-side Swift with Vapor.
1. Getting Started with Vapor 12 min |
2. Vapor Routing 14 min |
3. Leaf Templates 13 min |
4. Nesting Templates and Partials 8 min |
5. Vapor Demo: Tokenizr 21 min |
6. Setting up a Database with Fluent 19 min |
7. Creating, Updating, and Deleting Records with Fluent 19 min |
8. Vapor Futures 20 min |
9. Setting up Vapor with Postgresql 17 min |
10. UUID Primary Keys 13 min |
11. Timestamp Fields 4 min |
12. Refactoring to Protocols 12 min |
13. Parent Child Relationships and Foreign Keys 14 min |
14. Pivot Tables for Many to Many Relationships 14 min |
15. Vapor Controllers 15 min |
16. Decoding Request Parameters 9 min |
Episode Links
- Fluent SQLite
- Base - SQLite Editor
- twostraws/vapor-clean - A Vapor 3 template with no additional cruft.
Creating a Bare Vapor Project
We are going to start by creating a project that has nothing in it. This will help us understand how to set up a dependency like Fluent.
$ vapor new blog --template=https://github.com/twostraws/vapor-clean.git
Once that is created, start the initial build.
$ vapor build
Adding FluentSQLite with Swift Package Manager
We're going to use SQLite as our database for this demo. Let's open up Package.swift
and add our dependency:
// swift-tools-version:4.0
import PackageDescription
let package = Package(
name: "blog",
dependencies: [
.package(url: "https://github.com/vapor/vapor.git", from: "3.1.0"),
.package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0")
],
targets: [
.target(name: "App", dependencies: ["Vapor", "FluentSQLite"]),
.target(name: "Run", dependencies: ["App"]),
.testTarget(name: "AppTests", dependencies: ["App"]),
]
)
We can build again to fetch this new dependency and then generate an Xcode project:
$ vapor build
$ vapor xcode
Configuring the Database
We need to configure our application to use the database. Open up configure.swift
.
import Vapor
import FluentSQLite
public func configure(
_ config: inout Config,
_ env: inout Environment,
_ services: inout Services
) throws {
// Other setup ...
try services.register(FluentSQLiteProvider())
let db = try SQLiteDatabase(storage: .file(path: "db.sqlite"))
var dbConfig = DatabasesConfig()
dbConfig.add(database: db, as: .sqlite)
services.register(dbConfig)
}
This will create our database as a file, located in the built products directory. You can see this path output in the console when you run the application in case you want to inspect the database manually.
Creating a Model
All Fluent models must implement the Model
protocol. This provides information to the system about what type of primary key the model has, what the name of the table is, and whether it supports automatic timestamps like createdAt
and updatedAt
.
In most cases, you can use the Model
sub-protocol defined by the provider.
import Vapor
import FluentSQLite
final class Post : SQLiteModel {
var id: Int?
var title: String
var body: String
var author: String
var publishedAt: Date?
static let entity = "posts"
init(title: String, body: String, author: String) {
self.title = title
self.body = body
self.author = author
}
}
Configuring Migrations
To get our posts
table to be created, we need to make our model adopt the Migration
protocol:
extension Post : Migration { }
Then we need to configure migrations to run on application startup. In configure.swift
, after the database has been configured:
var migrations = MigrationConfig()
migrations.add(model: Post.self, database: .sqlite)
services.register(migrations)
We'll get the first migration for free, but as we alter this table and add new fields, we'll have to create migrations to update our database as well.