Comments (9)
@finestructure Ah yes, this is because in FluentKit
.json
is an alias for DatabaseSchema.DataType.dictionary(of: DataType?)
which PostgresConverterDelegate
interprets as SQLRaw("JSONB")
.
You should be able to do .sql(SQLRaw("JSON"))
in your migration to force it to be textual if you wanted to. You probably don't though but it's just a bit confusion the way it's set up.
from postgres-kit.
@finestructure Thanks for making this issue so easy to reproduce! It appears that PostgresDataEncoder
does not support summoning nested containers (it just fatalError
s). I don't have the full overview of whether it should but I can provide a workaround. By conforming ProductType
to PostgresJSONCodable
the whole encoding step is short-circuited and you should get the expected result.
from postgres-kit.
Hi @siemensikkema , thanks a lot for taking a look!
There's probably also another way to work around this issue. I haven't tried it in this instance yet but I'm pretty sure we have older encodable enums with associated types where we used
"key": null
to encode presence of keys and keys with values rather than nested containers. The reason I went for the new format is that with SE-0295 in Swift 5.5 I believe the standard auto-generated format is going to be the nested one.
I.e. any user trying to store an enum with associated types using Codable
synthesis will probably hit this exception.
I'll try your suggested workaround as that should allow me to retain the format and then I can just drop the PostgresJSONCodable
should support be added. I'll report back how it goes!
from postgres-kit.
Just to follow up: making ProductType
conform to PostgresJSONCodable
allows saving but not reading apparently:
/Users/sas/Projects/spi-server/Tests/AppTests/ProductTests.swift:59: error: -[AppTests.ProductTests test_Product_save] : XCTUnwrap failed: threw error "invalid field: type type: ProductType error: typeMismatch(App.ProductType, Swift.DecodingError.Context(codingPath: [], debugDescription: "Could not convert to ProductType: {\"library\": {\"_0\": \"automatic\"}}", underlyingError: nil))"
It saved to the db ok:
This is the test: https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/blob/e99471c81a2973253ed5867ec18a88a4f54da11c/Tests/AppTests/ProductTests.swift#L8
I've also double checked and we have no other enums with associated types marked as Codable
, so I'm not yet sure if that work-around would be feasible. (I'd also rather not introduce a custom coding conformance if it can be avoided and made forward compatible since we're talking about persisting results here.)
from postgres-kit.
So digging into this a bit further, it the problem was that the PostgresDataType
type when reading back is jsonb
. Making the conformance PostgresJSONBCodable
instead fixes that.
(As an aside, .json
in the field definition generates jsonb
in the schema. So maybe PostgresJSONCodable
should also try guard let value = try? postgresData.jsonb(as: Self.self) else {
in addition to just .json(as: Self.self)
?)
from postgres-kit.
@finestructure ah I missed that you needed JSONB. However, are you sure about it generating jsonb
? Looking at PostgresColumnType.swift
I see:
/// textual JSON data
public static var json: PostgresColumnType {
return .init(.json)
}
/// binary JSON data, decomposed
public static var jsonb: PostgresColumnType {
return .init(.jsonb)
}
from postgres-kit.
Mmm, here's our migration:
struct UpdateProductType: Migration {
func prepare(on database: Database) -> EventLoopFuture<Void> {
database.schema("products")
.deleteField("type")
.field("type", .json, .required)
.update()
}
func revert(on database: Database) -> EventLoopFuture<Void> {
database.schema("products")
.deleteField("type")
.field("type", .string, .required)
.update()
}
}
and here's the schema:
CREATE TABLE products (
id uuid PRIMARY KEY,
created_at timestamp with time zone,
updated_at timestamp with time zone,
version_id uuid REFERENCES versions(id) ON DELETE CASCADE,
name text NOT NULL,
targets text[] DEFAULT '{}'::text[],
type jsonb NOT NULL
);
This is true for all our .json
columns - they are jsonb
in the schema.
from postgres-kit.
This should work now.
from postgres-kit.
Yes, can confirm! I've just recently removed our workaround but forgot to close the issue. Thanks, Gwynne!
from postgres-kit.
Related Issues (20)
- Are transactions supported? HOT 4
- Improve pool use documentation? HOT 2
- Dependency to PostgresNIO is incorrect
- transaction HOT 2
- Using enums as dictionary keys
- swift 5.5 async await HOT 6
- PostGIS "geometry" type HOT 2
- URL is unable to be decoded HOT 3
- Usage of `try!` in repository README HOT 1
- Failing to decode enum throws incorrect error
- Add optional Application Name to Postgres Connection Info HOT 3
- Update use of `connect` and `authenticate` to fix warnings HOT 4
- Connection issue while URL contains "%" HOT 1
- Update to new PostgresNIO API HOT 1
- Standard sslmode URL params HOT 2
- SQLPostgresConfiguration does not allow the postgresql:// URL scheme
- `PostgresDataConvertible` should not be hard-deprecated till PostgresKit adopts newer APIs HOT 4
- URL is not supported as a postgres codable type
- Occasional Encoding Error HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from postgres-kit.