ULID tersilap disimpan sebagai UUID dalam pangkalan data (aplikasi symfony vanila)
P粉381463780
P粉381463780 2023-12-16 08:43:42
0
1
649

Semalam saya cuba melakukan apa yang Symfony laungkan dalam beberapa catatan blog (https://symfony.com/blog/new-in-symfony-5-2-doctrine-types-for-uuid-and-ulid) tetapi gagal . Saya ingin menyimpan ULID (dalam format "TTTTTTTTTTRRRRRRRRRR") dalam pangkalan data kerana ia bukan sahaja boleh diisih, tetapi ia juga mengandungi cap waktu yang sesuai untuk aplikasi saya. Walau bagaimanapun, apabila saya memberitahu atribut itu sebagai "type=ulid", ia disimpan dalam pangkalan data sebagai UUID (format: "xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx").

Saya debug selama setengah hari dan sangat jengkel dengan ini sehingga saya bermula dari awal dan masalah itu masih wujud.

Di mana silap saya?

(langkau ke pengepala ULID jika anda mahu, yang berikut mungkin kelihatan panjang tetapi 50% daripadanya hanyalah asas)

Symphony

Perkara yang saya lakukan berulang kali Diambil daripada https://symfony.com/doc/5.4/setup.html:

  1. stat shyt # 不存在
  2. composer 创建项目 symfony/sculpture:5.4.* shyt
  3. cd shyt;作曲家需要 webapp
  4. Adakah anda mahu memasukkan konfigurasi Docker dalam resipi? Ya (lalai)
  5. bin/console about Menunjukkan Symfony versi 5.4.10 dan PHP 7.4

ORM

Diambil daripada https://symfony.com/doc/5.4/doctrine.html:

  1. composer 需要 symfony/orm-pack
  2. composer 需要 --dev symfony/maker-bundle
  3. docker-compose up -d

Ralat: Tiada kumpulan alamat IPv4 yang tersedia dan tidak bertindih ditemui dalam kumpulan alamat lalai yang diberikan kepada rangkaian

Jadi saya menambah beberapa baris dalam fail docker-compose.override.yml:

networks:
  default:
    ipam:
      config:
        - subnet: 10.1.2.1/24

services:
  database:
  # [...] doctrine/doctrine-bundle stuff [...]
  networks:
    default:
      ipv4_address: 10.1.2.3
  1. Tetapkan DATABASE_URL dalam ".env" untuk hos "10.1.2.3"
  2. bin/console 学说:数据库:create (bodoh, tetapi seperti yang didokumenkan)

Tidak boleh mencipta 'apl' pangkalan data untuk sambungan bernama lalai Pengecualian berlaku semasa melaksanakan pertanyaan: SQLSTATE[42P04]: Pangkalan data pendua: 7 Ralat: "apl" pangkalan data sudah wujud

Nah, ya. Docker sudah melakukan ini.

  1. make:entity Ditangguh sehingga kami mempunyai fungsi ULID.

ULID

Kami telah condong ke https://symfony.com/doc/5.4/components/uid.html (terutama bahagian ULID):

  1. composer 需要 symfony/uid
  2. bin/console make:entity Product
  • "someProperty" sebagai "ulid" tidak boleh dibatalkan
  1. Semak entiti produk

Kelihatan hampir sama seperti dalam dokumentasi, kecuali ia mempunyai medan tambahan (kunci utama, integer) dan beberapa getter/setter.

  1. bin/console make:migration

Menguji entiti ULID

Di antaranya, kami mencipta entri pangkalan data secara pemrograman menggunakan ujian:

  1. composer 需要 phpunit Cipta entri pangkalan data secara pengaturcaraan
  2. bin/console --env=测试主义:migrations:migrate
  3. bin/console --env=测试主义:数据库:create
  4. Fail "tests/FooTest.php" mengandungi:
<?php

namespace AppTests;

use AppEntityProduct;
use AppRepositoryProductRepository;
use DoctrineORMEntityManager;
use SymfonyBundleFrameworkBundleTestKernelTestCase;
use SymfonyComponentUidUlid;

class FooTest extends KernelTestCase
{
    public function testFoo(): void
    {
        $product = new Product();
        $product->setSomeProperty(new Ulid());
        static::assertNotNull($product->getSomeProperty());

        self::getContainer()->get(ProductRepository::class)
            ->add($product);

        self::getContainer()->get('doctrine.orm.entity_manager')
            ->flush();
    }
}
  1. bin/console --env=test 主义:query:sql 'TRUNCATE Product' Hanya untuk memastikan
  2. bin/phpunit
  3. bin/console --env=测试主义:query:sql 'SELECT * FROM 产品'

Tunjukkan UUID, bukan ULID.

Tunjukkan ULID dan bukannya UUID dalam pangkalan data

Gunakan ULID sebagai kunci utama

Mula-mula bersihkannya dan kemudian laksanakan contoh yang ditunjukkan di https://symfony.com/doc/5.4/components/uid.html#ulids:

  1. rm 迁移/* Mulakan semula
  2. bin/console --env=测试主义:database:drop --force
  3. bin/console --env=测试主义:数据库:create
  4. bin/控制台主义:数据库:drop --force
  5. bin/console --env=测试主义:数据库:create
  6. Edit "src/Entity/Product.php" untuk memasukkan hanya ULID kedua daripada dokumentasi Contoh:
<?php

namespace AppEntity;

use DoctrineORMMapping as ORM;
use SymfonyComponentUidUlid;
use AppRepositoryProductRepository;

/**
 * @ORMEntity(repositoryClass=ProductRepository::class)
 */
class Product
{
    /**
     * @ORMId
     * @ORMColumn(type="ulid", unique=true)
     * @ORMGeneratedValue(strategy="CUSTOM")
     * @ORMCustomIdGenerator(class="doctrine.ulid_generator")
     */
    private $id;

    public function getId(): ?Ulid
    {
        return $this->id;
    }

    // ...

}

(Contoh dalam dokumentasi tiada baris repositori)

  1. bin/console make:migration
  2. bin/console --env=测试主义:migrations:migrate
  3. Ujian kini lebih mudah:
public function testFoo(): void
    {
        self::getContainer()->get(ProductRepository::class)
            ->add(new Product());

        self::getContainer()->get('doctrine.orm.entity_manager')
            ->flush();
    }
  1. bin/phpunit(Berisiko tidak mengapa)
  2. bin/console --env=测试主义:query:sql 'SELECT * FROM 产品'

Guna UUID dan bukannya ULID lagi

Pangkalan data menunjukkan UUID dan bukannya ULID

P粉381463780
P粉381463780

membalas semua(1)
P粉377412096

Agak lewat tetapi bagi sesiapa yang menghadapi isu ini, saya juga mempunyai pangkalan data yang menunjukkan UUID dan bukannya ULID, yang nampaknya merupakan tingkah laku yang diharapkan dalam Doktrin kerana anda boleh menggunakan UUID/ULID secara bergantian, bermakna walaupun anda akan UUID disimpan dalam pangkalan data tetapi entiti anda dipetakan ke ULID, apabila mendapatkan semula objek daripada pangkalan data anda akan mempunyai ULID, anda juga boleh mendapatkan objek yang sama menggunakan ULID atau UUID.

Sebagai contoh, saya mempunyai entiti pengguna yang pengecamnya mempunyai ULID, jadi objek yang disimpan akan mempunyai uuid seperti ini:

018477e6-eebc-164c-12e3-22ca8f1a88f3    myemail@mail.com    []

Jika saya mendapatkan semula pengguna saya menggunakan UUID itu, saya mendapat:

App\Entity\User {#430 ▼
 -id: "01GHVYDVNW2S615RS2SA7HN27K"
 -email: "myemail@mail.com"
 -roles: []
 #createdAt: DateTime @1668458933 {#423 ▶}
 #updatedAt: DateTime @1668458998 {#428 ▶}
 -password: "y$/2i9Ovc2lCQBRfSVgsnmoul1FhF.Kyki3irF6GQvrMrjacQX6ees6"
 -isVerified: true
}

Kini, jika anda menggunakan ULID itu untuk mendapatkan semula pengguna anda, ia juga akan berfungsi!

Jika anda memeriksa UUID, anda akan melihat bahawa objek yang dikembalikan mempunyai uuid yang ditukar kepada asas 32:

bash-5.1$ bin/console uuid:inspect 018477e6-eebc-164c-12e3-22ca8f1a88f3
----------------------- --------------------------------------
Label                   Value
----------------------- --------------------------------------
Version                 1                                     
  toRfc4122 (canonical)   018477e6-eebc-164c-12e3-22ca8f1a88f3  
  toBase58                1BsMRvKcgozP4Kw2m4Fb1C                
  toBase32                01GHVYDVNW2S615RS2SA7HN27K
----------------------- --------------------------------------

Akhir sekali, anda boleh mendapatkan uuid yang disimpan dengan menukarnya kepada refc4122 seperti ini:

bin/console ulid:inspect 01GHVYDVNW2S615RS2SA7HN27K
---------------------- --------------------------------------
Label                  Value
---------------------- --------------------------------------
toBase32 (canonical)   01GHVYDVNW2S615RS2SA7HN27K
toBase58               1BsMRvKcgozP4Kw2m4Fb1C
toRfc4122              018477e6-eebc-164c-12e3-22ca8f1a88f3
---------------------- --------------------------------------
Time                   2022-11-14 20:48:53.948 UTC
---------------------- --------------------------------------

Saya tidak pasti mengapa Prinsip tidak hanya menyimpan ULID, tetapi tingkah laku semasanya tidak menghalang anda daripada menggunakan ULID dalam projek anda. Harap ini membantu!

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan