昨天,我尝试了Symfony在博客文章(https://symfony.com/blog/new-in-symfony-5-2-doctrine-types-for-uuid-and-ulid)中的做法,但是失败了。我想在数据库中存储ULID(格式为“TTTTTTTTTTTTRRRRRRRRRRRRRR”),因为它们不仅可以排序,而且还包含一个时间戳,这对我的应用程序来说是完美的。但是当我告诉一个属性为“type=ulid”时,它被存储为UUID(格式为:“xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx”)。
我调试了半天,对此感到非常恼火,我从头开始,问题仍然存在。
我哪里做错了?
- (如果您愿意,可以跳到ULID标题,以下内容可能看起来很长,但其中50%都是基本内容)*
赛姆芬尼
我反复做的事情取自https://symfony.com/doc/5.4/setup.html:
stat shyt # does not exist
composer create-project symfony/skeleton:5.4.* shyt
cd shyt; composer require webapp
1.是否要包括配方中的Docker配置?是(默认)bin/console about
显示Symfony版本5.4.10和PHP 7.4
ORM
取自https://symfony.com/doc/5.4/doctrine.html:
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle
docker-compose up -d
错误:在默认值中找不到可用的非重叠IPv4地址池以分配给网络
因此我在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.在“.env”中,为主机“10.1.2.3“设置DATABASE_URL
bin/console doctrine:database:create
(愚蠢,但已记录)
无法为名为default的连接创建数据库“app”执行查询时出现异常:SQL状态[42 P04]:重复的数据库:7错误:数据库“app”已存在
是的,多克已经做过了.make:entity
被推迟到我们拥有ULID功能之后。
ULID
我们已经学习了https://symfony.com/doc/5.4/components/uid.html(特别是ULID部分):
composer require symfony/uid
bin/console make:entity Product
- 作为“ulid”的“someProperty”不可为空
1.检查产品实体
看起来几乎像文档中的一样,除了它有一个额外的字段(主键,一个整数)和一些getter/setter。
- bin/console make:迁移
测试ULID实体
在此期间,我们使用测试以编程方式创建DB条目:
composer require phpunit
以编程方式创建数据库条目bin/console --env=test doctrine:migrations:migrate
bin/console --env=test doctrine:database:create
1.文件“tests/FooTest.php”包含:
<?php
namespace App\Tests;
use App\Entity\Product;
use App\Repository\ProductRepository;
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Uid\Ulid;
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();
}
}
bin/console --env=test doctrine:query:sql 'TRUNCATE product'
只是为了确保- x1米15英寸
bin/console --env=test doctrine:query:sql 'SELECT * FROM product'
个
显示UUID而不是ULID。
Shows ULID instead of UUID in the database
使用ULID作为主键
首先清理一下,然后执行https://symfony.com/doc/5.4/components/uid.html#ulids:
rm migrations/*
重新开始bin/console --env=test doctrine:database:drop --force
- x1米19英寸1x
- x1米20英寸
bin/console --env=test doctrine:database:create
1.编辑“src/Entity/Product.php”,使其仅包含文档中的第二个ULID示例:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Ulid;
use App\Repository\ProductRepository;
/**
* @ORM\Entity(repositoryClass=ProductRepository::class)
*/
class Product
{
/**
* @ORM\Id
* @ORM\Column(type="ulid", unique=true)
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class="doctrine.ulid_generator")
*/
private $id;
public function getId(): ?Ulid
{
return $this->id;
}
// ...
}
(文档中的示例缺少存储库行)
bin/console make:migration
bin/console --env=test doctrine:migrations:migrate
1.测试现在简单一点:
public function testFoo(): void
{
self::getContainer()->get(ProductRepository::class)
->add(new Product());
self::getContainer()->get('doctrine.orm.entity_manager')
->flush();
}
bin/phpunit
(风险可以接受)- x1米25英寸1x
同样是UUID而不是ULID
2条答案
按热度按时间6yt4nkrj1#
我也在尝试ULID,并遵循相同的文档(https://symfony.com/blog/new-in-symfony-5-2-doctrine-types-for-uuid-and-ulid)。我注意到您在代码中做了一件与文档不同的事情。
在实体变更中:
至
并添加以下内容
这将使ULID工作。
转储的内容如下所示(抱歉,这是我测试ulid时控制台中的转储,但我希望它能提供您所需的信息):
在数据库中,它如下所示:Ulid in mariaDB
我希望这能帮上忙。
wdebmtf22#
这有点晚了,但对于任何面临这个问题的人来说,我也有一个显示UUID而不是ULID的数据库,这似乎是理论上的预期行为,因为您可以互换使用UUID/ULID,这意味着即使您有UUID存储在数据库中,但您的实体Map到ULID,您在从数据库检索对象时也将有一个ULID,您也可以使用ULID或UUID检索相同的对象。
例如,我有一个用户实体,其标识符为ULID,因此存储的对象将具有如下所示的uuid:
如果我用UUID检索我用户,我将得到:
现在,如果您使用ULID来检索您用户,它也将工作!
如果进一步检查该UUID,您将看到返回的对象将该UUID转换为base 32:
最后,您可以通过将其转换为refc 4122来获取存储uuid,如下所示:
我不知道为什么doctrine不只是存储ULID,但是它目前的行为并没有阻止你在你的项目中使用ULID。希望这能有所帮助!