Is it possible to nest YAML anchors hierarchically? - yaml

I'm new to working with YAML. I'd like to know if it is possible to 'nest' YAML anchors as I have attempted in the example below. Unfortunately, I get an error YAMLException: unidentified alias "foo" at line 13, column 19: category: *foo ^
namespace: &namespace-definition
name: "Hellow world"
value: "hw"
categories: &categories
- &foo:
name: "foo"
namespace: *namespace-definition
- &bar:
name: "bar"
namespace: *namespace-definition
keys:
- name: "element1"
category: *foo
- name: "element2"
category: *bar
Is there another way to achieve what I am trying to do, or is it impossible?

The anchors in your example are named foo: and bar:, not foo and bar.
Remove the colon after them and it will work:
namespace: &namespace-definition
name: "Hellow world"
value: "hw"
categories: &categories
- &foo
name: "foo"
namespace: *namespace-definition
- &bar
name: "bar"
namespace: *namespace-definition
keys:
- name: "element1"
category: *foo
- name: "element2"
category: *bar

Related

GraphQL Python Strawberry refactor common types

I am using Python 3.10 and Strawberry 0.139
Is there any way to refractor out like-terms to write less code for defining types?
Lets say I have two types in my schema
#strawberry.type
class Home(Address):
name: str
location: str
description: str
phone: int
#strawberry.type
class Business(Address):
name: str
fax: int
location: str
description: str
phone: int
Is there a way I can refractor out like terms in a class using the abc library. Note that I am not referring to interfaces where you have to write in the inherited code. Something like this:
from abc import ABC
class Contact(ABC):
location: str
description: str
phone: int
#strawberry.type
class Home(Address):
name: str
#strawberry.type
class Business(Address):
name: str
fax: int
Inherit from a base strawberry.type. Unlike interfaces, the base type won't be in the schema (unless explicitly included).
#strawberry.type
class Contact:
location: str
description: str
phone: int
#strawberry.type
class Home(Contact):
name: str
#strawberry.type
class Business(Contact):
name: str
fax: int

yaml anchor extend object in list

Suppose I had a yaml that looked like
common_animals: &common_animals
animals:
- name: "bird"
can_swim: false
- name: "fish"
can_swim: true
extended_animals:
<<: *common_animals
# here I want to add attribute to the bird object in the list `can_fly: true`
# here I want to add attribute to the fish object in the list `can_fly: false`
How might I achieve this?

Multiple refs in YAML duplicated mapping key at line 43 error

I am trying to get multiple refs into a YAML document to break down the size but get duplicated mapping key at line 43 error, is there a way to do this ? or am I just trying to break it down to much, the initial entry file goes to paths
'''
paths:
$ref: "./paths/_index.yaml"
then from there seperates to :
/Users:
get:
$ref: "./user/listUsers.yaml"
post:
$ref: "./user/createUsers.yaml"
/Users/{UserId}:
get:
$ref: "./user/showUserById.yaml"
list users then goes onto users schema as so :
content:
application/json:
schema:
ArrayOfUsers:
type: array
items:
$ref: '../../schemas/User.yaml'
'404':
description: no users were found
default:
$ref: "../../responses/UnexpectedError.yaml"
I then wanted to break up the parts in the users model so I could use them again instead of having a giant block
type: object
description: random corp
properties:
# contact_info:
# description: contact information
# type: object
# properties:
# firstName:
# type: string
# lastName:
# type: string
# companyName:
# type: string
# email:
# type: string
# phone:
# type: string
# address_info:
# description: address information of the alitus customer
# type: object
# properties:
# firstName:
# type: string
# lastName:
# type: string
# companyName:
# type: string
# email:
# type: string
# phone:
# type: string
# account_reference:
# description: Alitus customers number and id for referencing
# type: object
# properties:
# id:
# type: integer
# format: int64
# accountNumber:
# type: integer
# format: int64
$ref: "/Login/LoginDetails.yaml"
$ref: "/packageDetails/PackageDetails.yaml"
example:
type: array
items:
anyOf:
$ref: "../examples/UserExample.yaml"
xml:
name: User
Am I trying to separate it to much or can this be done in 3.0
here is the error
There was an error while processing your files. Please fix the error and save the file.
#/paths/~1Users/get/responses/200/content/application~1json/schema: duplicated mapping key at line 43, column 3:
$ref: ../../schemas/User.yaml
#/paths/~1Users~1{UserId}/get/responses/200/content/application~1json/schema: duplicated mapping key at line 43, column 3:
$ref: ../../schemas/User.yaml
#/components/schemas/User: duplicated mapping key at line 43, column 3:
$ref: ./User.yaml
I figured it out, I just had to have one reference to an object that contained the multiple elements
so now I just call one
$ref: "/test.yaml"
and in the test file we just reference all the objects like so
Login:
$ref: "/Login/LoginDetails.yaml"
Package:
$ref: "/packageDetails/PackageDetails.yaml"

Update value in key value pair in yml file using ruby [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have a YAML file:
DATA_SVC_GEN_CONF_ATTR:
-
-
-
name: validationCodeNum
value: 1
-
name: validationCodeSymbol
value: "val1"
-
name: sql
value: Test
-
name: sqlByGridArea
value: Test1
I want to replace the value of the key sql from "Test" to "Select * from table".
What I am trying is:
asset.getAttributes.getList.each{|a|
if a.getName == "sqlByGridArea"
a.setValue "Select * from table"
(attrib_defs).map!{|a| a.map{|k,v| "#{k}=#{v}"}.join(',')}
end
asset.with_attributes attrib_defs
Here's how to test whether your YAML is valid, and how I generate YAML for use in files or elsewhere:
require 'yaml'
str = <<EOT
DATA_SVC_GEN_CONF_ATTR:
-
-
-
name: validationCodeNum
value: 1
-
name: validationCodeSymbol
value: "val1"
-
name: sql
value: Test
-
name: sqlByGridArea
value: Test1
EOT
data = YAML.load(str)
# => {"DATA_SVC_GEN_CONF_ATTR"=>
# [[[{"name"=>"validationCodeNum", "value"=>1},
# {"name"=>"validationCodeSymbol", "value"=>"val1"},
# {"name"=>"sql", "value"=>"Test"},
# {"name"=>"sqlByGridArea", "value"=>"Test1"}]]]}
YAML would complain if it couldn't parse the data. If it could and the data wasn't what you expect the output help you diagnose the problem.
When I want to create a YAML file, especially one that's complex, I start with the actual data structure and let YAML generate the serialized version of it:
data = {
'DATA_SVC_GEN_CONF_ATTR' =>
[
[
[
{
'name' => 'validationCodeNum',
'value' => 1
},
{
'name' => 'validationCodeSymbol',
'value' => 'val1'
},
{
'name' => 'sql',
'value' => 'Test'
},
{
'name' => 'sqlByGridArea',
'value' => 'Test1'
}
]
]
]
}
puts data.to_yaml
# >> ---
# >> DATA_SVC_GEN_CONF_ATTR:
# >> - - - name: validationCodeNum
# >> value: 1
# >> - name: validationCodeSymbol
# >> value: val1
# >> - name: sql
# >> value: Test
# >> - name: sqlByGridArea
# >> value: Test1
Moving on... To change elements in a YAML file you can treat the file as text, read it line-by-line, read it by slurping it, or have YAML open it and change the resulting object then have YAML rewrite it.
Slurping files is OK if you're sure the data will fit in memory and you can easily find the section you want to change. Reading it line-by-line often makes it easier to find specific text because you're dealing with individual lines, not the whole file.
Using YAML is the easiest I think as it reduces the change of a badly written regex doing the wrong thing.
data = <<EOT
---
DATA_SVC_GEN_CONF_ATTR:
- - - name: validationCodeNum
value: 1
- name: validationCodeSymbol
value: val1
- name: sql
value: Test
- name: sqlByGridArea
value: Test1
EOT
Pretending that data was the content of a YAML file on disk, it'd be loaded and parsed using YAML.load_file. In this example I'm loading as a string so I have to use load:
object = YAML.load(data)
The data is now parsed so it can be manipulated easily:
object['DATA_SVC_GEN_CONF_ATTR'].first.first[2]['name'] = "Select * from table"
Then it can be written back out:
puts object.to_yaml # => nil
# >> ---
# >> DATA_SVC_GEN_CONF_ATTR:
# >> - - - name: validationCodeNum
# >> value: 1
# >> - name: validationCodeSymbol
# >> value: val1
# >> - name: Select * from table
# >> value: Test
# >> - name: sqlByGridArea
# >> value: Test1
If this is a mission-critical (production) file, you'd want to do the appropriate rename, write, delete steps to protect the data in-case of errors, but that's the gist of it.
Your data structure is very questionable though. You're using a nested array-of-array-of-array just to hold your hashes, which is not very common or easily understood. Instead it should be reduced to a single array:
data = <<EOT
---
DATA_SVC_GEN_CONF_ATTR:
- name: validationCodeNum
value: 1
- name: validationCodeSymbol
value: val1
- name: sql
value: Test
- name: sqlByGridArea
value: Test1
EOT
object = YAML.load(data)
# => {"DATA_SVC_GEN_CONF_ATTR"=>
# [{"name"=>"validationCodeNum", "value"=>1},
# {"name"=>"validationCodeSymbol", "value"=>"val1"},
# {"name"=>"sql", "value"=>"Test"},
# {"name"=>"sqlByGridArea", "value"=>"Test1"}]}
object['DATA_SVC_GEN_CONF_ATTR'][2]['name'] = "Select * from table"

How to list YAML records based on categories?

I have a YAML database with data in the following format:
- product:
name: Apples
- product:
name: Grapes
How can I update it so each product is assigned to a category, then on my page I can have an unordered list the products under a category heading?
For example:
Fruit
*Apples
*Grapes
Vegetables
*Tomatoes
*Broccoli
I tried searching for an example of something like this, but couldn't find anything. Is it possible to do something like this?
- category:
name: fruit
- product:
name: Apples
- product:
name: Grapes
- category:
name: vegetables
- product:
name: Tomatoes
- product:
name: Broccoli
I'd suggest two schemes, the first groups all products together:
products:
- name: Apple
type: Fruit
- name: Grape
type: Fruit
- name: Tomato
type: Vegetable
- name: Brocoli
type: Vegetable
The other scheme would be using on group for each type of product
fruits:
- name: Apple
- name: Grape
vegetable:
- name: Tomato
- name: Brocoli
To actually display this you would just load the yaml data with something like (forgive me if this has changed... it's been a while since I used yaml):
require 'yaml'
data = YAML.load_file('data.yml')
data is essentially just a ruby hash so you can display whatever you like by traversing it.
EDIT:
If the second option is what you want. Try the following:
require 'yaml'
data = YAML.load_file('data.yml')
data.each do |category, products|
puts "#{category}"
products.each do |product|
puts "\t#{products}"
end
end
Output should be:
fruits
Apple
Grape
vegetable
Tomato
Brocoli
If you want to output html, then modify it to something like:
require 'yaml'
data = YAML.load_file('data.yml')
data.each do |category, products|
puts "#{category}"
puts "<ul>"
products.each do |product|
puts "<li>#{products}</li>"
end
puts "</ul>"
end
You can see the differences to add the html formatting is very simple and you should be able to further modify this to your needs.
You could just assign a category attribute to each Product:
- name: Apples
category: Fruit
- name: Grapes
category: Fruit
- name: Tomatoes
category: Vegetables
- name: Broccoli
category: Vegetables
...and then load the data for all Fruits:
require "yaml"
YAML.load("products.yml").select{ |product| product["category"] == "Fruit" }
# => [{"name"=>"Apples", "category"=>"Fruit"}, {"name"=>"Grapes", "category"=>"Fruit"}]

Resources